Spring事务管理理解分析.docx_第1页
Spring事务管理理解分析.docx_第2页
Spring事务管理理解分析.docx_第3页
Spring事务管理理解分析.docx_第4页
Spring事务管理理解分析.docx_第5页
免费预览已结束,剩余1页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

spring自建事务管理模块。而且这个事务管理是一个抽象设计,可以应用到很多场合,包括普通的DataSource,jta,jms和hibernate上。 要正确使用spring的事务,首先需要了解spring在事务设计上的一些概念 统观spring事务,围绕着两个核心PlatformTransactionManager和TransactionStatus PlatformTransactionManager直译过来就是平台相关事务,这里的平台指的是“事务源”,包括刚才我说的DataSource,jta等等。这些无一不是一个事务源。广义的说,凡是可以完成事务性操作的对象,都可以设计出相对应的PlatformTransactionManager,只要这个事务源支持commit,rollback和getTransaction语意。 查看spring代码,可以发现这些manager实现事务,就是调用事务源的事务操作方法 比如 HibernateTransactionManager Java代码 1. protectedvoiddoCommit(DefaultTransactionStatusstatus); 2. HibernateTransactionObjecttxObject=(HibernateTransactionObject);status.getTransaction(); 3. if(status.isDebug();); 4. logger.debug(CommittingHibernatetransactiononsession+ 5. txObject.getSessionHolder();.getSession();+); 6. 7. try 8. txObject.getSessionHolder();.getTransaction();.commit(); 9. 10. . 11. 12. protected void doCommit(DefaultTransactionStatus status); HibernateTransactionObject txObject = (HibernateTransactionObject); status.getTransaction();if (status.isDebug();); logger.debug(Committing Hibernate transaction on session +txObject.getSessionHolder();.getSession(); + );try txObject.getSessionHolder();.getTransaction();.commit();.jdbc 的DataSourceTransactionManager Java代码 1. protectedvoiddoCommit(DefaultTransactionStatusstatus); 2. DataSourceTransactionObjecttxObject=(DataSourceTransactionObject);status.getTransaction(); 3. Connectioncon=txObject.getConnectionHolder();.getConnection(); 4. if(status.isDebug();); 5. logger.debug(CommittingJDBCtransactiononconnection+con+); 6. 7. try 8. mit(); 9. 10. . 11. protected void doCommit(DefaultTransactionStatus status); DataSourceTransactionObject txObject = (DataSourceTransactionObject); status.getTransaction();Connection con = txObject.getConnectionHolder();.getConnection();if (status.isDebug();); logger.debug(Committing JDBC transaction on connection + con + );try mit();.那么PlatformTransactionManager以什么依据处理事务呢? 是TransactionStatus 查看api发现这个接口有三个方法 isNewTransaction() ,isRollbackOnly(),setRollbackOnly() PlatformTransactionManager就是根据前两个方法决定是否要创建一个新事务,是要递交还是回滚。至于第三个方法是改变事务当前状态的,很多地方都要用到,偏偏PlatformTransactionManager自身好像不怎么用,毕竟事务状态的改变是由程序员代码决定的,不需要一个manager多管闲事。 总结上面所说的,spring的事务由PlatformTransactionManager管理,manager最后调用事务源的方法来实现一个事务过程。而manager通过TransactionStatus 来决定如何实现。 接下去说spring事务中的TransactionTemplate和TransactionInterceptor TransactionTemplate其实和spring中其他的template的作用类似,起到化简代码的作用,不要被它那么长的名字吓倒了,事实上这个template并不是什么非常核心的对象。如果比较学究派的,可以去看看template设计模式,在此就不再对此赘述了。 为什么要有TransactionTemplate?先来看看如果没有TransactionTemplate,我们的代码该怎么写 先来看看spring reference中的一段代码 Java代码 1. DefaultTransactionDefinitiondef=newDefaultTransactionDefinition(); 2. def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); 3. 4. TransactionStatusstatus=transactionManager.getTransaction(def); 5. 6. try 7. /executeyourbusinesslogichere 8. catch(MyExceptionex); 9. transactionManager.rollback(status); 10. throwex; 11. 12. transactionMmit(status);DefaultTransactionDefinition def = new DefaultTransactionDefinition();def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);TransactionStatus status = transactionManager.getTransaction(def);try / execute your business logic here catch (MyException ex); transactionManager.rollback(status); throw ex;transactionMmit(status);这是直接使用transactionManager的例子,可以看到真正执行business logic 的地方是在try当中那段,前后的代码都是为了完成事务管理的。如果每个business logic都要写上那么一段,我肯定是疯了。我们翻出TransactionTemplate的代码看看他怎么化简了我们的代码 Java代码 1. publicObjectexecute(TransactionCallbackaction);throwsTransactionException 2. TransactionStatusstatus=this.transactionManager.getTransaction(this); 3. Objectresult=null; 4. try 5. result=action.doInTransaction(status); 6. 7. catch(RuntimeExceptionex); 8. /transactionalcodethrewapplicationexception-rollback 9. rollbackOnException(status,ex); 10. throwex; 11. 12. catch(Errorerr); 13. /transactionalcodethrewerror-rollback 14. rollbackOnException(status,err); 15. throwerr; 16. 17. this.transactionMmit(status); 18. returnresult; 19. public Object execute(TransactionCallback action); throws TransactionException TransactionStatus status = this.transactionManager.getTransaction(this);Object result = null;try result = action.doInTransaction(status);catch (RuntimeException ex); / transactional code threw application exception - rollbackrollbackOnException(status, ex);throw ex;catch (Error err); / transactional code threw error - rollbackrollbackOnException(status, err);throw err;this.transactionMmit(status);return result;同上面的代码如出一辙,前后是事务处理代码,当中那段result = action.doInTransaction(status);是我们的应用代码。至于action是什么,全看各位的需要了。但是有一点要主要,如果利用TransactionTemplate,那么他不管你扔出什么异常都会回滚事务,但是回滚的是哪个事务呢?继续挖代码 Java代码 1. privatevoidrollbackOnException(TransactionStatusstatus,Throwableex);throwsTransactionException 2. if(logger.isDebugEnabled();); 3. logger.debug(Initiatingtransactionrollbackonapplicationexception,ex); 4. 5. try 6. this.transactionManager.rollback(status); 7. 8. catch(RuntimeExceptionex2); 9. logger.error(Applicationexceptionoverriddenbyrollbackexception,ex); 10. throwex2; 11. 12. catch(Errorerr); 13. logger.error(Applicationexceptionoverriddenbyrollbackerror,ex); 14. throwerr; 15. 16. private void rollbackOnException(TransactionStatus status, Throwable ex); throws TransactionException if (logger.isDebugEnabled();); logger.debug(Initiating transaction rollback on application exception, ex);try this.transactionManager.rollback(status);catch (RuntimeException ex2); logger.error(Application exception overridden by rollback exception, ex);throw ex2;catch (Error err); logger.error(Application exception overridden by rollback error, ex);throw err;真相大白,是对template所持有的某个transactionManager进行回滚。所以如果你的应用代码用的是事务源a的一些资源,比如到服务器a的一个datasource,但是你的transactionManager管理的是另一些资源,比如服务器b的一个datasource,代码铁定不会正常运行 特别是在一些多事务源的程序里,这点千万不能搞错。如果多个事务源之间要完成全局事务,还是老老实实用分布式事务管理服务吧(jta) 那么TransactionInterceptor是干什么的?这个是spring 的声明式事务的支持方式。因为用TransactionTemplate要硬编码,而且调整事务策略很麻烦(不是说不能调。举个例子原来程序抛出异常A需要回滚,现在不需要要,我就可以把a catch吃掉。这时候template就不会回滚了。但是每次调整都要重写编码。)而用TransactionInterceptor就可以将这些调整写在配置中。我们再来挖TransactionInterceptor的代码 Java代码 1. publicObjectinvoke(MethodInvocationinvocation);throwsThrowable 2. /Workoutthetargetclass:maybenull. 3. /TheTransactionAttributeSourceshouldbepassedthetargetclass 4. /aswellasthemethod,whichmaybefromaninterface 5. ClasstargetClass=(invocation.getThis();!=null);?invocation.getThis();.getClass();:null; 6. 7. /Createtransactionifnecessary 8. TransactionInfotxInfo=createTransactionIfNecessary(invocation.getMethod();,targetClass); 9. 10. ObjectretVal=null; 11. try 12. /Thisisanaroundadvice. 13. /Invokethenextinterceptorinthechain. 14. /Thiswillnormallyresultinatargetobjectbeinginvoked. 15. retVal=ceed(); 16. 17. catch(Throwableex); 18. /targetinvocationexception 19. doCloseTransactionAfterThrowing(txInfo,ex); 20. throwex; 21. 22. finally 23. doFinally(txInfo); 24. 25. doCommitTransactionAfterReturning(txInfo); 26. 27. returnretVal; 28. public Object invoke(MethodInvocation invocation); throws Throwable / Work out the target class: may be null./ The TransactionAttributeSource should be passed the target class/ as well as the method, which may be from an interfaceClass targetClass = (invocation.getThis(); != null); ? invocation.getThis();.getClass(); : null;/ Create transaction if necessaryTransactionInfo txInfo = createTransactionIfNecessary(invocation.getMethod();, targetClass);Object r

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论