MyBatis事务管理

这是我参与8月更文挑战的第11天,活动详情查看:8月更文挑战

MyBatis事务管理

在上一篇文章中我们讲解了MyBatis的入门程序,在MyBatis的核心配置文件中,我们在配置环境的时候有< transactionManager type="JDBC"></transactionManager>这么一个标签,该标签代表的就是配置一个事务管理器,其type属性表示配置的事务类型。在这里的type属性值即事务的类型可以有两种,除了上面的JDBC类型,还有MANAGED类型,这两种类型最主要的区别就是JDBC类型采用的是JDBC提供的事务管理机制,而MANAGED类型则是将事务管理交由容器处理,如交由Spring处理。下面将分别介绍这两种事务管理。关于事务的相关知识,可以查看我的另外一篇文章 ⏩ # MySQL事务

image.png

?Transaction

在MyBatis中事务被抽象成一个Transation接口,该接口定义了一系列操作事务的方法,包括获取连接、提交事务、回滚事务、关闭连接。该接口有三个实现类,分别为JdbcTransaction、ManagedTransaction、SpringManagedTransaction

  • Transaction接口源码如下
public interface Transaction {
    Connection getConnection() throws SQLException;

    void commit() throws SQLException;

    void rollback() throws SQLException;

    void close() throws SQLException;

    Integer getTimeout() throws SQLException;
}
复制代码
  • 其类图如下

image.png

采用JDBC的事务管理机制

在了解JDBC的事务管理机制之前,我们需要先知道MyBatis事务管理机制是如何运行的。首先,在MyBatis初始化加载主配置文件的过程中,会对我们主配置文件进行解析,MyBatis会根据我们< transactionManager >标签中配置的type属性来生成一个TransactionFactory事务工厂实例 ,TransactionFactory是一个接口,其主要有JdbcTransactionFactory和ManagedTransactionFactory这两个实现类,其中定义了两种创建Transaction的方法,一种根据Connection来创建,另一种根据Datasource数据源、事务隔离级别、是否自动提交来创建Transaction。如果type为JDBC,则生成一个JdbcTransactionFactory实例,它会创建JDBC类型的事务,就是JdbcTransaction。有了JdbcTransaction,JdbcTransaction就会从DataSource获取连接对象Connection,在事务处理上,JdbcTransaction是对java.sql.Connection的一个包装,它是使用Connection对象进行事务的管理。

  • TransactionFactory接口源码
public interface TransactionFactory {
    default void setProperties(Properties props) {
    }
    //根据指定的Connection来创建Transaction
    Transaction newTransaction(Connection var1);
    //根据数据源、事务隔离级别、是否自动提交事务来创建Transaction
    Transaction newTransaction(DataSource var1, TransactionIsolationLevel var2, boolean var3);
}
复制代码
  • TransactionFactory接口的实现类JdbcTransactionFactory源码,用来创建JdbcTransaction实例
public class JdbcTransactionFactory implements TransactionFactory {
    public JdbcTransactionFactory() {
    }
    
    //创建一个JdbcTransaction实例
    public Transaction newTransaction(Connection conn) {
        return new JdbcTransaction(conn);
    }

    public Transaction newTransaction(DataSource ds, TransactionIsolationLevel level, boolean autoCommit) {
        return new JdbcTransaction(ds, level, autoCommit);
    }
}
复制代码
  • JdbcTransaction实现类源码
public class JdbcTransaction implements Transaction {
    protected Connection connection;
    protected DataSource dataSource;
    protected TransactionIsolationLevel level;
    protected boolean autoCommit;

    //获取连接
    public Connection getConnection() throws SQLException {
        if (this.connection == null) {
            this.openConnection();
        }

        return this.connection;
    }
    //事务提交
    public void commit() throws SQLException {
        if (this.connection != null && !this.connection.getAutoCommit()) {
            if (log.isDebugEnabled()) {
                log.debug("Committing JDBC Connection [" + this.connection + "]");
            }

            this.connection.commit();
        }

    }
    //事务回滚
    public void rollback() throws SQLException {
        if (this.connection != null && !this.connection.getAutoCommit()) {
            if (log.isDebugEnabled()) {
                log.debug("Rolling back JDBC Connection [" + this.connection + "]");
            }

            this.connection.rollback();
        }

    }
    //关闭连接
    public void close() throws SQLException {
        if (this.connection != null) {
            this.resetAutoCommit();
            if (log.isDebugEnabled()) {
                log.debug("Closing JDBC Connection [" + this.connection + "]");
            }

            this.connection.close();
        }

    }

   ......略
}
复制代码

采用MANAGED的事务管理机制

采用MANAGED类型的事务管理机制与JDBC的事务管理机制不同的是MANAGED类型是将事务管理交由容器来处理,MyBatis本身不会去实现事务管理的相关操作。如果我们的type属性值设置为MANAGED类型,最终会生成ManagedTransaction实例,,通过对源码的观察,则,可以发现Transaction的实现类ManagedTransaction中的commit方法和rollback方法没有具体实现,所以ManagedTransaction是让容器来管理事务Transaction的整个生命周期。我们考虑一下,如果MyBatis和Spring框架整合,那么Spring会怎么来管理事务呢?关于Spring事务,可以看我的另一篇文章⏩Spring事务

  • ManagedTransaction类部分源码
public class ManagedTransaction implements Transaction {
    private DataSource dataSource;
    private TransactionIsolationLevel level;
    private Connection connection;
    private final boolean closeConnection;

    public Connection getConnection() throws SQLException {
        if (this.connection == null) {
            this.openConnection();
        }

        return this.connection;
    }

    public void commit() throws SQLException {
        //没有内容
    }

    public void rollback() throws SQLException {
         //没有内容
    }

    public void close() throws SQLException {
        if (this.closeConnection && this.connection != null) {
            if (log.isDebugEnabled()) {
                log.debug("Closing JDBC Connection [" + this.connection + "]");
            }

            this.connection.close();
        }

    }
    
    略...
}
复制代码

?以上就是对MyBatis事务管理的介绍,如果有错误的地方,还请留言指正,如果觉得本文对你有帮助那就点个赞?吧???

默认标题_动态分割线_2021-07-15-0.gif

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享