快速业务通道

Spring声明式事务管理源码解读之事务提交 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-17

Spring声明式事务管理源码解读之事务提交

时间:2011-03-29 javaeye 张荣华

在下面的文章中,我讲会多次提到第一篇文章,第一篇文章是:Spring声明式事务管 理源码解读之事务开始

如果要理解事务提交的话,理解事务开始是一个前提条件,所以请先看第一篇文章,再 来看这篇

如果你仔细看下去,我想肯定是有很多收获,因为我们确实能从spring的代码和思想 中学到很多东西。

正文:

其实俺的感觉就是事务提交要比事务开始复杂,看事务是否提交我们还是要回到 TransactionInterceptor类的invoke方法

Java代码

public Object invoke(MethodInvocation invocation) throws Throwable {      // Work out the target class: may be <code>null</code>.      // The TransactionAttributeSource should be passed the target class      // as well as the method, which may be from an interface      Class targetClass = (invocation.getThis() != null) ? invocation.getThis().getClass() : null;      // Create transaction if necessary.      TransactionInfo txInfo = createTransactionIfNecessary (invocation.getMethod(), targetClass);      Object retVal = null;      try {        // This is an around advice.        // Invoke the next interceptor in the chain.        // This will normally result in a target object being invoked.        retVal = invocation.proceed();      }      catch (Throwable ex) {        // target invocation exception        doCloseTransactionAfterThrowing(txInfo, ex);        throw ex;      }      finally {        doFinally(txInfo);//业务方法出栈后必须先执行的一个方法      }      doCommitTransactionAfterReturning(txInfo);      return retVal;    }

其中的doFinally(txInfo)那一行很重要,也就是说不管如何,这个doFinally方法都 是要被调用的,为什么它这么重要呢,举个例子:

我们还是以propregation_required来举例子吧,假设情况是这样的,AService中有一 个方法调用了BService中的,这两个方法都处在事务体之中,他们的传播途径都是 required。那么调用开始了,AService的方法首先入方法栈,并创建了TransactionInfo 的实例,接着BService的方法入栈,又创建了一个TransactionInfo的实例,而重点要说 明的是TransactionInfo是一个自身关联的内部类,第二个方法入栈时,会给新创建的 TransactionInfo的实例设置一个属性,就是TransactionInfo对象中的private TransactionInfo oldTransactionInfo;属性,这个属性表明BService方法的创建的 TransactionInfo对象是有一个old的transactionInfo对象的,这个oldTransactionInfo 对象就是AService方法入栈时创建的TransactionInfo对象,我们还记得在 createTransactionIfNecessary方法里有这样一个方法吧:

Java代码

protected TransactionInfo createTransactionIfNecessary(Method method, Class targetClass) {          // We always bind the TransactionInfo to the thread, even if we didn''t create      // a new transaction here. This guarantees that the TransactionInfo stack      // will be managed correctly even if no transaction was created by this aspect.      txInfo.bindToThread();      return txInfo;    } 就是这个bindToThread()方法在作怪: private void bindToThread() {        // Ex

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号