之前使用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