标签: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