ibatis源码浅析- 事务
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; } } }