對數據庫的事務而言,應該具備如下幾點:建立(create)、提交(commit)、回滾(rollback)、關閉(close)。對應地,MyBatis將事務抽象成了Transaction接口:java
org.apache.ibaits.transaction.Transaction接口定義了獲取Connection鏈接、提交、回滾和關閉的功能。mysql
MyBatis的事務管理分爲兩種形式:spring
JdbcTransaction使用JDBC的事務管理機制:JdbcTransaction是使用的java.sql.Connection 上的commit和rollback功能,JdbcTransaction只是至關於對java.sql.Connection事務處理進行了一次包裝(wrapper),Transaction的事務管理都是經過java.sql.Connection實現的。sql
ManagedTransaction使用MANAGED的事務管理機制:這種機制MyBatis自身不會去實現事務管理,而是讓程序的容器如(JBOSS,Weblogic)來實現對事務的管理。使用ManagedTransaction的commit和rollback功能不會對事務有任何的影響,它什麼都不會作,它將事務管理的權利移交給了容器來實現數據庫
SpringManagedTransaction使用Spring的事務管理機制:它其實也是經過使用JDBC來進行事務管理的,當spring的事務管理有效時,不須要操做commit/rollback/close,spring事務管理會自動幫咱們完成apache
這二者的類圖以下所示:緩存
在Mybatis的配置文件中能夠配置事務管理方式以下:mybatis
<?xml version="1.0" encoding="UTF-8"?> app
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> ui
<configuration>
<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://localhost:3306/mybatis" />
<property name="username" value="root" />
<property name="password" value="XDP" />
</dataSource>
</environment>
</environments>
</configuration>
<environment>節點定義了鏈接某個數據庫的信息,其子節點<transactionManager> 的type 會決定咱們用什麼類型的事務管理機制。
MyBatis事務的建立是交給TransactionFactory 事務工廠來建立的,若是咱們將<transactionManager>的type 配置爲"JDBC",那麼,在MyBatis初始化解析<environment>節點時,會根據type="JDBC"建立一個JdbcTransactionFactory工廠,其源碼以下:
/**
* 解析<transactionManager>節點,建立對應的TransactionFactory
* @param context
* @return
* @throws Exception
*/
private TransactionFactory transactionManagerElement(XNode context) throws Exception {
if (context != null) {
String type = context.getStringAttribute("type");
Properties props = context.getChildrenAsProperties();
/*
在Configuration初始化的時候,會經過如下語句,給JDBC和MANAGED註冊對應的工廠類
typeAliasRegistry.registerAlias("JDBC", JdbcTransactionFactory.class);
typeAliasRegistry.registerAlias("MANAGED", ManagedTransactionFactory.class);
下述的resolveClass(type).newInstance()會建立對應的工廠實例
*/
TransactionFactory factory = (TransactionFactory) resolveClass(type).newInstance();
factory.setProperties(props);
return factory;
}
throw new BuilderException("Environment declaration requires a TransactionFactory.");
}
MyBatis對<transactionManager>節點的解析會生成 TransactionFactory實例;而對<dataSource>解析會生成datasouce實例。做爲<environment>節點,會根據TransactionFactory和DataSource實例建立一個Environment對象,代碼以下所示:
private void environmentsElement(XNode context) throws Exception {
if (context != null) {
if (environment == null) {
environment = context.getStringAttribute("default");
}
for (XNode child : context.getChildren()) {
String id = child.getStringAttribute("id");
//是和默認的環境相同時,解析之
if (isSpecifiedEnvironment(id)) {
//1.解析<transactionManager>節點,決定建立什麼類型的TransactionFactory
TransactionFactory txFactory = transactionManagerElement(child.evalNode("transactionManager"));
//2. 建立dataSource
DataSourceFactory dsFactory = dataSourceElement(child.evalNode("dataSource"));
DataSource dataSource = dsFactory.getDataSource();
//3. 使用了Environment內置的構造器Builder,傳遞id 事務工廠TransactionFactory和數據源DataSource
Environment.Builder environmentBuilder = new Environment.Builder(id)
.transactionFactory(txFactory)
.dataSource(dataSource);
configuration.setEnvironment(environmentBuilder.build());
}
}
}
}
Environment表示着一個數據庫的鏈接,生成後的Environment對象會被設置到Configuration實例中,以供後續的使用。
事務工廠Transaction定義了建立Transaction的兩個方法:一個是經過指定的Connection對象建立Transaction,另外是經過數據源DataSource來建立Transaction。與JDBC 和MANAGED兩種Transaction相對應,TransactionFactory有兩個對應的實現的子類:
經過事務工廠TransactionFactory很容易獲取到Transaction對象實例。咱們以JdbcTransaction爲例,看一下JdbcTransactionFactory是怎樣生成JdbcTransaction的,代碼以下:
public class JdbcTransactionFactory implements TransactionFactory {
public void setProperties(Properties props) {
}
/**
* 根據給定的數據庫鏈接Connection建立Transaction
* @param conn Existing database connection
* @return
*/
public Transaction newTransaction(Connection conn) {
return new JdbcTransaction(conn);
}
/**
* 根據DataSource、隔離級別和是否自動提交建立Transacion
*
* @param ds
* @param level Desired isolation level
* @param autoCommit Desired autocommit
* @return
*/
public Transaction newTransaction(DataSource ds, TransactionIsolationLevel level, boolean autoCommit) {
return new JdbcTransaction(ds, level, autoCommit);
}
}
JdbcTransactionFactory會建立JDBC類型的Transaction,即JdbcTransaction。相似地,ManagedTransactionFactory也會建立ManagedTransaction。
https://blog.csdn.net/luanlouis/article/details/37992171