Mybatis源碼分析之(八)Mybatis事務管理機制

事務指作爲單個邏輯工作單元執行的一系列操作,要麼完全地執行,要麼完全地不執行。對於數據庫操作來說是必不可少的。

在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實現爲空。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章