之前使用JDBC的时候,若是要开启事务,咱们须要调用conn.setAutoCommit(false)方法来关闭自动提交,以后才能进行事务操做,不然每一次对数据库的操做都会持久化到磁盘中。java
而mybatis呢,若是底层使用JDBC(在mybatis.xml中配置的transactionManager标签的type设为jdbc的话),那么,mybatis会默认开启事务,也就是说,mybatis默认是关闭自动提交的。数据库
在mybatis中,若是咱们执行了数据库的修改操做(insert、update、delete),必须调用session.commit()方法,所作的修改才能持久化到磁盘。apache
在openSession()时,传入true,便可关闭事务。session
有PeopleMapp.xml,配置有一个insert命令:mybatis
<insert id="insertPeople" parameterType="People"> insert into people values (null, #{name}, #{age}) </insert>
测试代码以下:app
package lixin.gan.test; import java.io.IOException; import java.io.InputStream; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import lixin.gan.pojo.People; public class TestTransaction { public static void main(String[] args){ InputStream config = null; try { config = Resources.getResourceAsStream("mybatis.xml"); } catch (IOException e) { e.printStackTrace(); } SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(config); SqlSession session = factory.openSession(); People p = new People(); p.setName("王五3"); p.setAge(88); try { int affected_rows =session.insert("lixin.gan.mapper.PeopleMapper.insertPeople", p); if (affected_rows <= 0) { throw new Exception("第1个操做失败"); } else { System.out.println("第1个操做成功"); } } catch (Exception e) { // 捕获到异常,将操做回滚 //e.printStackTrace(); session.rollback(); } p.setName("王五222222222222222222222222222"); p.setAge(77); try { int affected_rows =session.insert("lixin.gan.mapper.PeopleMapper.insertPeople", p); if (affected_rows <= 0) { throw new Exception("第2个操做失败"); } else { System.out.println("第2个操做成功"); } } catch (Exception e) { session.rollback(); } session.commit(); session.close(); System.out.println("over"); } }
第二次调用对象的setName设置的name属性值,超过了people表中的name字段长度,因此插入操做会失败,因而会抛出异常,一场被捕获后,当前的session就会本次session存在期间的全部操做。测试
一、要想使用事务,请将数据库表的引擎设置为InnoDb,别用MyISAM。ui
二、若是是DML,请必定要记得commit(),不然操做不会生效。xml