MyBatis原始碼閱讀——MyBatis對事務的處理過程分析
事務管理器
在 MyBatis 中有兩種型別的事務管理器(也就是 type=”[JDBC|MANAGED]”):
<environments default="development"> <environment id="development"> <!-- 配置事務管理器 --> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://127.0.0.1/learn?useUnicode=true&characterEncoding=utf-8"/> <property name="username" value="root"/> <property name="password" value="12345"/> </dataSource> </environment> </environments>
* JDBC – 這個配置就是直接使用了 JDBC 的提交和回滾設定,它依賴於從資料來源得到的連線來管理事務作用域。即利用java.sql.Connection物件完成對事務的提交(commit())、回滾(rollback())、關閉(close())等
* MANAGED – 這個配置幾乎沒做什麼。它從來不提交或回滾一個連線,而是讓容器來管理事務的整個生命週期(比如 JEE 應用伺服器的上下文)。 預設情況下它會關閉連線,然而一些容器並不希望這樣,因此需要將 closeConnection 屬性設定為 false 來阻止它預設的關閉行為。這種機制MyBatis自身不會去實現事務管理,而是讓程式的容器如(JBOSS,Weblogic)來實現對事務的管理。
< transactionManager type="MANAGED">
< property name="closeConnection" value="false"/>
</ transactionManager>
如果你正在使用 Spring + MyBatis,則沒有必要配置事務管理器, 因為 Spring 模組會使用自帶的管理器來覆蓋前面的配置。
這兩種事務管理器型別都不需要任何屬性。它們不過是類型別名,換句話說,你可以使用 TransactionFactory 介面的實現類的完全限定名或類型別名代替它們。
事務使用
JdbcTransaction
JdbcTransaction由TransactionFactory->openSessionFromConnection()方法生成
從JdbcTransaction的原始碼中,你應該可以看出,JdbcTransaction主要是對java.sql.Connection事務處理中的事務進行了一層封裝。
ManagedTransaction
在ManagedTransaction原始碼中,commit,rollback方法全是空的,它讓容器管理事務transaction的整個生命週期。也就是說,ManagedTransaction不會幫我們commit和rollback。
執行一段程式碼看下效果:
String resource = "mybatis/conf/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//從 XML 中構建 SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession(false);
Blog blog = new Blog();
blog.setBlogTitle("這是標題1");
blog.setBlogContent("這是內容2");
blog.setCreateTime(new Date());
try {
BlogMapper mapper = session.getMapper(BlogMapper.class);
mapper.insert(blog);
session.commit();
}catch (Exception e){
//手動回滾
session.rollback();
}finally {
session.close();
}
在我們未開啟自動提交的情況下(事務必須關閉)它都是執行的空操作。不會影響資料庫。
SpringManagedTransaction
在mybatis-spring jar包中,在SqlSession執行sql時通過用SpringManagedTransaction代替mybatis的JdbcTransaction,讓SqlSession從spring的ThreadLocal中獲取jdbc connection。關於Spring的事務處理原理可以看下此篇部落格:https://blog.csdn.net/qq_18860653/article/details/80049281