事務指作爲單個邏輯工作單元執行的一系列操作,要麼完全地執行,要麼完全地不執行。對於數據庫操作來說是必不可少的。
在Mybatis框架中有二種事務實現,一種是JdbcTransaction,另一種是ManagedTransaction。他們的配置都是通過environment中的transactionManager 標籤來配置的。加載過程在
Mybatis源碼分析之(二)根據配置文件創建SqlSessionFactory(Configuration的創建過程)中,歡迎大家移步去看看。
<environments default="development">
<environment id="development">
<!-- type爲”JDBC”時,使用JdbcTransaction管理事務。
type爲”managed”時,使用ManagedTransaction管理事務-->
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
JdbcTransaction
public class JdbcTransaction implements Transaction {
private static final Log log = LogFactory.getLog(JdbcTransaction.class);
//與數據庫的連接
protected Connection connection;
//數據源信息
protected DataSource dataSource;
//表示事務級別
protected TransactionIsolationLevel level;
//是否自動提交
protected boolean autoCommmit;
public JdbcTransaction(DataSource ds, TransactionIsolationLevel desiredLevel, boolean desiredAutoCommit) {
dataSource = ds;
level = desiredLevel;
autoCommmit = desiredAutoCommit;
}
public JdbcTransaction(Connection connection) {
this.connection = connection;
}
@Override
public Connection getConnection() throws SQLException {
if (connection == null) {
openConnection();
}
return connection;
}
@Override
public void commit() throws SQLException {
if (connection != null && !connection.getAutoCommit()) {
if (log.isDebugEnabled()) {
log.debug("Committing JDBC Connection [" + connection + "]");
}
//最終使用的是connection的commit
connection.commit();
}
}
@Override
public void rollback() throws SQLException {
if (connection != null && !connection.getAutoCommit()) {
if (log.isDebugEnabled()) {
log.debug("Rolling back JDBC Connection [" + connection + "]");
}
//最終使用的是connection的rollback
connection.rollback();
}
}
@Override
public void close() throws SQLException {
if (connection != null) {
resetAutoCommit();
if (log.isDebugEnabled()) {
log.debug("Closing JDBC Connection [" + connection + "]");
}
//最終使用的是connection的close
connection.close();
}
}
}
也就是說JdbcTransaction其實只是在jdbc的connection上面封裝了一下,實際使用的其實還是jdbc的事務。、
ManagedTransaction
public class ManagedTransaction implements Transaction {
private static final Log log = LogFactory.getLog(ManagedTransaction.class);
//數據源信息
private DataSource dataSource;
//表示事務級別
private TransactionIsolationLevel level;
//與數據庫的連接
private Connection connection;
//關閉鏈接的標誌符
private boolean closeConnection;
public ManagedTransaction(Connection connection, boolean closeConnection) {
this.connection = connection;
this.closeConnection = closeConnection;
}
public ManagedTransaction(DataSource ds, TransactionIsolationLevel level, boolean closeConnection) {
this.dataSource = ds;
this.level = level;
this.closeConnection = closeConnection;
}
@Override
public Connection getConnection() throws SQLException {
if (this.connection == null) {
//打開鏈接
openConnection();
}
return this.connection;
}
//commit不做任何處理
@Override
public void commit() throws SQLException {
// Does nothing
}
//rollback不做任何處理
@Override
public void rollback() throws SQLException {
// Does nothing
}
@Override
public void close() throws SQLException {
if (this.closeConnection && this.connection != null) {
if (log.isDebugEnabled()) {
log.debug("Closing JDBC Connection [" + this.connection + "]");
}
this.connection.close();
}
}
protected void openConnection() throws SQLException {
if (log.isDebugEnabled()) {
log.debug("Opening JDBC Connection");
}
//通過dataSource獲取鏈接
this.connection = this.dataSource.getConnection();
if (this.level != null) {
this.connection.setTransactionIsolation(this.level.getLevel());
}
}
}
Mybatis不再控制會話的事務,而是讓容器來管理transaction的整個生命週期 。
因爲ManagedTransaction的commit和rollback沒有任何實現,若你是單用了Mybatis一個框架,那麼使用ManagedTransaction作爲事務實現,那麼當我們無法將一個數據庫操作過程,作爲一個事務提交上去。因爲ManagedTransaction裏commit實現爲空。