ibatis默认提供四种事务 transaction 类图
ExternalTransactionConfig :commit rollbak方法都是个空实现 spring默认使用的这个
UserProvidedTransaction :支持外部Connection 可以和jdbc混合使用
JdbcTransaction :原生jdbc事务
JtaTransaction:分布式事务
TransactionConfig 主要负责创建事务对象 每一个Transaction都有一个TransactionConfig TransactionConfig类图
事务控制实例代码
try {
sqlmapclient.startTransaction ();
.....
sqlmapclient.commitTransaction ();
} finally {
sqlmapclient.endTransaction ();
}
startTransaction方法 :
根据sqlMapConfig配置 调用TransactionManager类中的begin方法 创建一个新的事务 具体事务的创建由TransactionConfig接口的实现类完成
创建完成后 将事务(Transaction) 保存到SessionScope中 并设置当前sessionScope中的TransactionState为STATE_STARTED状态
SssionScope简单理解为ibatis上下文对象 它与SqlMapSession对象绑定 而SqlMapSession对象与当前线程绑定 SssionScope它持有当前Transaction, TransactionState
TransactionManager begin方法
public void begin(SessionScope sessionScope, int transactionIsolation) throws SQLException, TransactionException {
// .. 省略
//TransactionConfig 创建一个新的Transaction
trans = config.newTransaction(transactionIsolation);
sessionScope.setCommitRequired(false);
//当前事务对象保存到sessionScope
sessionScope.setTransaction(trans);
//设置当前事务状态
sessionScope.setTransactionState(TransactionState.STATE_STARTED);
}
JdbcTransactionConfig newTransaction方法
public Transaction newTransaction(int transactionIsolation) {
return new JdbcTransaction(dataSource, transactionIsolation);
}
commitTransaction 方法
间接的调用了TrasactionManager的commit方法 提交事务 如果提交成功 设置事务状态为已提交状态
TransactionManager commit方法
public void commit(SessionScope sessionScope) throws SQLException, TransactionException {
Transaction trans = sessionScope.getTransaction();
TransactionState state = sessionScope.getTransactionState();
//..略
//isCommitRequired 强制提交 可能出现异常
if (sessionScope.isCommitRequired() || config.isForceCommit()) {
//提交事务
trans.commit();
sessionScope.setCommitRequired(false);
}
//如果trans.commit()执行失败 这句不会执行 设置状态为已提交状态
sessionScope.setTransactionState(TransactionState.STATE_COMMITTED);
}
JdbcTransaction commit方法
public void commit() throws SQLException, TransactionException {
if (connection != null) {
connection.commit();
}
}
endTransaction 收尾工作
①.根据commitTransaction阶段 提交的事务状态 判断是不是需要回滚 ,
②.关闭数据库连接 , 清理当前线程的sessionScope
TransactionManager end 方法
public void end(SessionScope sessionScope) throws SQLException, TransactionException {
//从SessionScope获取Transaction TransactionState
Transaction trans = sessionScope.getTransaction();
TransactionState state = sessionScope.getTransactionState();
//...略
try {
if (trans != null) {
try {
//如果不是已提交状态 执行回滚操作
if (state != TransactionState.STATE_COMMITTED) {
if (sessionScope.isCommitRequired() || config.isForceCommit()) {
//执行回滚操作
trans.rollback();
sessionScope.setCommitRequired(false);
}
}
} finally {
//清理preparedStatements map集合 关闭PreparedStatement
sessionScope.closePreparedStatements();
//关闭当前Connection
trans.close();
}
}
} finally {
sessionScope.setTransaction(null);
//重新设置事务状态 为结束状态
sessionScope.setTransactionState(TransactionState.STATE_ENDED);
}
}
JdbcTransaction
rollback方法
public void rollback() throws SQLException, TransactionException {
if (connection != null) {
connection.rollback();
}
}
close方法 关闭当前数据库连接
public void close() throws SQLException, TransactionException {
if (connection != null) {
try {
isolationLevel.restoreIsolationLevel(connection);
} finally {
connection.close();
connection = null;
}
}
}