1. 程式人生 > 其它 >mybatis原始碼解讀:transaction包(事務管理功能)

mybatis原始碼解讀:transaction包(事務管理功能)

技術標籤:mybaits原始碼mybatis原始碼

歡迎關注本人公眾號:

mybatis的transaction包是負責進行事務管理的包,該包內包含2個子包:jdbc子包中包含基於jdbc進行事務管理的類,managed子包中包含基於容器進行事務管理的類。

1.事務概述

事務即資料庫事務,是資料庫執行過程中的一個邏輯單元。事務有以下4個特性:

Atomicity(原子性):事務必須被作為一個整體執行,要麼全部執行, 要麼全部不執行。不允許只執行其中的一部分。

Consistency(一致性):事務應該保證資料庫從一致性狀態轉換到另一個一致性狀態。一致性狀態是指資料庫中資料的完整性約束。

Isolation(隔離性):多個事務併發執行時, 事務不會互相干擾。

Durability(永續性):一旦事務提交,則其所做的修改就會永久儲存到資料庫中。

2.事務介面及工廠

整個transaction包採用了工廠方法模式實現,TransactionFactory是所有事務工廠的介面。

public interface TransactionFactory {  /**   * 配置工廠的屬性   * @param props 工廠的屬性   */  default void setProperties(Properties props) {    // NOP}  /**   * 從給定的連線中獲取一個事務
* @param conn 給定的連線 * @return 獲取的事務物件 */TransactionnewTransaction(Connectionconn); /** * 從給定的資料來源中獲取事務,並對事務進行一些配置 * @param dataSource 資料來源 * @param level 資料隔離級別 * @param autoCommit 是否自動提交事務 * @return 獲取的事務物件 */ Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level, boolean autoCommit);
}

Transaction是所有事務的介面。

public interface Transaction {  /**   * 獲取該事務對應的資料庫連線   * @return 資料庫連線   * @throws SQLException   */  Connection getConnection() throws SQLException;    /**   * 提交事務   * @throws SQLException   */  void commit() throws SQLException;    /**   * 回滾事務   * @throws SQLException   */  void rollback() throws SQLException;   /**   * 關閉對應的資料連線   * @throws SQLException   */  void close() throws SQLException;  /**   * 讀取設定的事務超時時間   * @return 事務超時時間   * @throws SQLException   */  Integer getTimeout() throws SQLException;}

TransactionFactory介面與Transaction介面都有2套實現,分別在jdbc包和managed包中。

3.jdbc事務

jdbc包中存放的是實現jdbc事務的JdbcTransaction類及其對應的工廠類,

JdbcTransaction類是jdbc事務的管理類,具體的事務操作是由JdbcTransaction類直接呼叫Connection類提供的事務方法來完成的。

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 autoCommit;  public JdbcTransaction(DataSource ds, TransactionIsolationLevel desiredLevel, boolean desiredAutoCommit) {    dataSource = ds;    level = desiredLevel;    autoCommit = desiredAutoCommit;  }   /**   * 提交事務   * @throws SQLException   */  @Override  public void commit() throws SQLException {    // 連線存在且不會自動提交事務    if (connection != null && !connection.getAutoCommit()) {      if (log.isDebugEnabled()) {        log.debug("Committing JDBC Connection [" + connection + "]");      }      // 呼叫connection物件的方法提交事務      connection.commit();    }  }  /**   * 回滾事務   * @throws SQLException   */  @Override  public void rollback() throws SQLException {    if (connection != null && !connection.getAutoCommit()) {      if (log.isDebugEnabled()) {        log.debug("Rolling back JDBC Connection [" + connection + "]");      }      connection.rollback();    }  }  }

JdbcTransactionFactory類負責生產JdbcTransaction物件。

public class JdbcTransactionFactory implements TransactionFactory {  @Override  public Transaction newTransaction(Connection conn) {    return new JdbcTransaction(conn);  }  @Override  public Transaction newTransaction(DataSource ds, TransactionIsolationLevel level, boolean autoCommit) {    return new JdbcTransaction(ds, level, autoCommit);  }}

4.容器事務

managed包中存放的是實現容器事務的ManagedTransaction類及其對應的工廠類。

在ManagedTransaction類中可以看到commit,rollback等方法內都沒有任何邏輯操作,這是因為相關的事務操作都委託給了容器進行管理。

public class ManagedTransaction implements Transaction {  private static final Log log = LogFactory.getLog(ManagedTransaction.class);  // 資料來源  private DataSource dataSource;  // 事務隔離級別  private TransactionIsolationLevel level;  // 資料庫連線  private Connection connection;  // 是否關閉資料庫連線  private final boolean closeConnection;    /**   * 提交事務   * @throws SQLException   */  @Override  public void commit() throws SQLException {    // Does nothing  }  /**   * 回滾事務   * @throws SQLException   */  @Override  public void rollback() throws SQLException {    // Does nothing  }  }

比如mybatis和spring整合時,mybatis中拿到的資料庫連線物件是spring提供的。spring可以通過xml配置,註解等多種方式來管理事務(即決定事務何時開始,提交,回滾)。當然,這種情況下,事務的最終實現也是由Connection物件的相關方法實現的。整個過程中,mybatis不需要處理任何事務操作,全都委託給spring即可。