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协议 。转载请注明出处!