Transaction
1. Transcation
在实践开发中,控制数据库事务是一件非常重要的工作,Mybatis使用Transaction接口对数据库事务进行了抽象,Transcation接口的定义如下:
public interface Transaction {
/**
* 获取对应的数据库连接对象
* Retrieve inner database connection.
* @return DataBase connection
* @throws SQLException
*/
Connection getConnection() throws SQLException;
/**
* 提交事务
* Commit inner database connection.
* @throws SQLException
*/
void commit() throws SQLException;
/**
* 回滚事务
* Rollback inner database connection.
* @throws SQLException
*/
void rollback() throws SQLException;
/**
* 关闭数据库连接
* Close inner database connection.
* @throws SQLException
*/
void close() throws SQLException;
/**
* 获取事务超时时间
* Get transaction timeout if set.
* @throws SQLException
*/
Integer getTimeout() throws SQLException;
}
Transaction接口有JdbcTranscation和ManagedTranscation两个实现,其对象分别由JdbcTranscationFactory和ManagedTranscationFactoy负责创建。这里也使用利用了工厂方法模式。

1.1. JdbcTranscation
JdbcTranscation依赖JDBC Connection控制事务的提交和回滚。JdbcTranscation中字段的含义如下所示:
/**
* 事务对应的数据库连接
*/
protected Connection connection;
/**
* 数据库连接所属的DataSource
*/
protected DataSource dataSource;
/**
* 事务的隔离级别
*/
protected TransactionIsolationLevel level;
/**
* 是否自动提交
*/
protected boolean autoCommit;
JdbcTranscation的构造方法有两个,分别是传递了Connection的,另一个没有传递的,代码如下所示:
/**
* 使用此构造方法,设置了除连接以外的值,至于connection字段的值,在调用{@link Transaction#getConnection()}的时候,
* 调用到{@link DataSource#getConnection()}获取,
*
* 通过这种方式,Connection对象中设置的事务的隔离级别和是否自动提交属性,不会覆盖(除非为null)。
* @param ds
* @param desiredLevel
* @param desiredAutoCommit
*/
public JdbcTransaction(DataSource ds, TransactionIsolationLevel desiredLevel, boolean desiredAutoCommit) {
dataSource = ds;
level = desiredLevel;
autoCommit = desiredAutoCommit;
}
/**
* 使用此构造方法,事务的隔离级别和是否自动提交使用的都是Connection中的配置
* @param connection
*/
public JdbcTransaction(Connection connection) {
this.connection = connection;
}
这两者的区别在代码注释中也讲得很清楚了,下面是设计到创建JdbcTranscation对象涉及到的其他方法:
@Override
public Connection getConnection() throws SQLException {
if (connection == null) {
openConnection();
}
return connection;
}
protected void openConnection() throws SQLException {
if (log.isDebugEnabled()) {
log.debug("Opening JDBC Connection");
}
connection = dataSource.getConnection();
if (level != null) {
connection.setTransactionIsolation(level.getLevel());
}
setDesiredAutoCommit(autoCommit);
}
JdbcTranscation还有其他方法,例如:commit()和rollback()等,都很简单,不在阐述。
1.2. ManagedTranscation
ManagedTranscation的实现更加简单,它同样依赖其中的dataSource字段获取连接,但其commit()和rollback()方法都是空实现,事务的提交和回滚都要依赖容器管理的,ManagedTranscation通过closeConnection字段的值控制数据库连接的关闭行为。
2. TranscationFactory
TranscationFactory接口定义了配置新建TranscationFactory对象的方法,以及创建Transcation对象的方法,代码如下:
public interface TransactionFactory {
/**
* 配置TransactionFactory对象,一般紧跟着创建完成之后,完成对TransactionFactory的自定义配置
* Sets transaction factory custom properties.
* @param props
*/
default void setProperties(Properties props) {
// NOP
}
/**
* 在指定的连接上创建Transaction对象
* Creates a {@link Transaction} out of an existing connection.
* @param conn Existing database connection
* @return Transaction
* @since 3.1.0
*/
Transaction newTransaction(Connection conn);
/**
* 从指定数据源中获取数据库连接,并在此连接上创建Transaction对象
* Creates a {@link Transaction} out of a datasource.
* @param dataSource DataSource to take the connection from
* @param level Desired isolation level
* @param autoCommit Desired autocommit
* @return Transaction
* @since 3.1.0
*/
Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level, boolean autoCommit);
}
在实践中,Mybatis通常会与Spring继承使用,数据库的事务是交给Spring进行管理的,其中接口为SpringManagedTranscation。
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!