这是我参与8月更文挑战的第11天,活动详情查看:8月更文挑战
MyBatis事务管理
在上一篇文章中我们讲解了MyBatis的入门程序,在MyBatis的核心配置文件中,我们在配置环境的时候有< transactionManager type="JDBC"></transactionManager>
这么一个标签,该标签代表的就是配置一个事务管理器,其type属性表示配置的事务类型。在这里的type属性值即事务的类型可以有两种,除了上面的JDBC类型,还有MANAGED类型,这两种类型最主要的区别就是JDBC类型采用的是JDBC提供的事务管理机制,而MANAGED类型则是将事务管理交由容器处理,如交由Spring处理。下面将分别介绍这两种事务管理。关于事务的相关知识,可以查看我的另外一篇文章 ⏩ # MySQL事务。
?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;
}
复制代码
- 其类图如下
采用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事务管理的介绍,如果有错误的地方,还请留言指正,如果觉得本文对你有帮助那就点个赞?吧???