}
}
还有一点需要说明的是,AService的方法在执行之前创建的transactionstatus确实是 通过这个方法创建的,但是,BService的方法在执行之前创建transactionstatus的方法 就与这个不一样了,下面会有详解。
Spring声明式事务管理源码解读之事务提交(3)
时间:2011-03-29 javaeye 张荣华
回顾了事务开始时所调用的方法之后,是不是觉得现在对spring如何处理事务越来越 清晰了呢。由于这么几个方法的调用,每个方法入栈之前它的事务状态就已经被设置好了 。这个事务状态就是为了在方法出栈时被调用而准备的。
让我们再次回到BService中的方法出栈的那个时间段,看看spring都做了些什么,我 们知道,后入栈的肯定是先出栈,BService中的方法后入栈,拿它肯定要先出栈了,它出 栈的时候是要判断是否要提交事务,释放资源的,让我们来看看TransactionInterceptor 的invoke的最后那个方法doCommitTransactionAfterReturning:
Java代码
protected void doCommitTransactionAfterReturning(TransactionInfo txInfo) {
if (txInfo != null && txInfo.hasTransaction()) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking commit for transaction on " + txInfo.joinpointIdentification());
}
this.transactionManager.commit(txInfo.getTransactionStatus ());
//瞧:提交事务时用到了表明事务状态的那个TransactionStatus对象了。
}
}
看这个方法的名字就知道spring是要在业务方法出栈时提交事务,貌似很简单,但是 事实是这样的吗? 我们接着往下看。
Java代码
public final void commit(TransactionStatus status) throws TransactionException {
DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
if (defStatus.isCompleted()) {
throw new IllegalTransactionStateException(
"Transaction is already completed - do not call commit or rollback more than once per transaction");
}
if (defStatus.isLocalRollbackOnly()) {
if (defStatus.isDebug()) {
logger.debug("Transactional code has requested rollback");
}
processRollback(defStatus);
return;
}
if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
if (defStatus.isDebug()) {
logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
}
processRollback(defStatus);
throw new UnexpectedRollbackException(
"Transaction has been rolled back because it has been marked as rollback- only");
}
processCommit(defStatus);
}
上面这段代码就是transactionmanager中的commit,但是看上去,它又把自己的职责 分配给别人了,从代码里我们看到,如果事务已经结束了就抛异常,如果事务是 rollbackonly的,那么就rollback吧,但是按照正常流程,我们还是想来看一下,事务的 提交,就是processCommit(status)这个方法吧。
Java代码
private void processCommit(DefaultTransactionStatus status) throws TransactionException {
try {
boolean befor
|