标签:ibatis
接上篇继续事务的提交和结束流程如下。
SqlMapClientImpl的commitTransaction操作,类似startTransaction,是最终由SqlMapExecutorDelege的commitTransaction完成的。
/** * Commit the transaction on a session * * @param sessionScope - the session * @throws SQLException - if the transaction could not be committed */ public void commitTransaction(SessionScope sessionScope) throws SQLException { try { // Auto batch execution if (sessionScope.isInBatch()) { executeBatch(sessionScope); } sqlExecutor.cleanup(sessionScope); txManager.commit(sessionScope); } catch (TransactionException e) { throw new NestedSQLException("Could not commit transaction. Cause: " + e, e); } }TransactionManager的commit
public void commit(SessionScope sessionScope) throws SQLException, TransactionException { Transaction trans = sessionScope.getTransaction(); TransactionState state = sessionScope.getTransactionState(); if (state == TransactionState.STATE_USER_PROVIDED) { throw new TransactionException("TransactionManager could not commit. " + "A user provided connection is currently being used by this session. " + "You must call the commit() method of the Connection directly. " + "The calling .setUserConnection (null) will clear the user provided transaction."); } else if (state != TransactionState.STATE_STARTED && state != TransactionState.STATE_COMMITTED ) { throw new TransactionException("TransactionManager could not commit. No transaction is started."); } System.out.println("hello:"+(sessionScope.isCommitRequired() || config.isForceCommit())); if (sessionScope.isCommitRequired() || config.isForceCommit()) { trans.commit(); sessionScope.setCommitRequired(false); } sessionScope.setTransactionState(TransactionState.STATE_COMMITTED); }Transaction的commit
public void commit() throws SQLException, TransactionException { if (connection != null) { connection.commit(); } }
事务提交操作执行完成后,事务状态被置为提交状态,有增删改操作时,commitRequired标识为真;如果没有异常的话,那么当前SessionScope的SQL操作都被提交。
类似startTransaction,都是转发给SqlMapExecutorDelegate的endTransaction。
/** * End the transaction on a session * * @param sessionScope - the session * @throws SQLException - if the transaction could not be ended */ public void endTransaction(SessionScope sessionScope) throws SQLException { try { try { sqlExecutor.cleanup(sessionScope); } finally { txManager.end(sessionScope); } } catch (TransactionException e) { throw new NestedSQLException("Error while ending transaction. Cause: " + e, e); } }TransactionManager的end
public void end(SessionScope sessionScope) throws SQLException, TransactionException { Transaction trans = sessionScope.getTransaction(); TransactionState state = sessionScope.getTransactionState(); if (state == TransactionState.STATE_USER_PROVIDED) { throw new TransactionException("TransactionManager could not end this transaction. " + "A user provided connection is currently being used by this session. " + "You must call the rollback() method of the Connection directly. " + "The calling .setUserConnection (null) will clear the user provided transaction."); } try { if (trans != null) { try { if (state != TransactionState.STATE_COMMITTED) { if (sessionScope.isCommitRequired() || config.isForceCommit()) { trans.rollback(); sessionScope.setCommitRequired(false); } } } finally { sessionScope.closePreparedStatements(); trans.close(); } } } finally { sessionScope.setTransaction(null); sessionScope.setTransactionState(TransactionState.STATE_ENDED); } }
事务的提交操作会根据当前SessionScope的事务信息判断是否需要回滚,只有当前事务状态为非提交状态,同时,提交标识为真时,才会调用Transaction的rollback操作。在两种情况下会出现SQL的回滚:
第一种,在MappedStatement的executeUpdate操作中,会设置事务的提交标识为真,并且只有在正确执行完成SQL后才会设置事务状态为已提交状态。如果整个流程中出现异常,那么这条SQL就会回滚。
第二种,用户执行了startTransaction,但是没有调用commitTransaction方法,那么这期间的SQL都会回滚。
Finally分支中会关闭所有的JDBC语句已经Connection,并设置事务状态为结束状态。至此,一次完整的SQL执行结束。标签:ibatis
原文地址:http://blog.csdn.net/wojiushiwo945you/article/details/45055903