快速业务通道

Spring事务管理高级应用难点剖析: 第2部分 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-13
   - Initiating transaction commit 2010-02-20 12:38:57,203 DEBUG [main]  (HibernateTransactionManager.java:652)   - Committing Hibernate  transaction on Session  [org.hibernate.impl.SessionImpl@83020] ④ 2010-02-20 12:38:57,203 DEBUG [main] (JDBCTransaction.java:103) - commit  ⑤

Spring事务管理高级应用难点剖析: 第2部分(4)

时间:2012-04-26 IBM 陈雄华

仔细观察这段输出日志,在①处 UserService#logon() 开启一个新的事务 ,在②处 ScoreService#addScore() 方法加入到①处开启的事务上下文中。③处的输出是 ScoreService#addScore() 方法内部的输出,汇报此时数据源激活的连接数为 1,这清楚地告 诉我们 Hibernate 和 JDBC 这两种数据访问技术在同一事务上下文中“共用”一个 连接。在④处,提交 Hibernate 事务,接着在⑤处触发调用底层的 Connection 提交事务。

从以上的运行结果,我们可以得出这样的结论:使用 Hibernate 事务管理器后,可以 混合使用 Hibernate 和 Spring JDBC 数据访问技术,它们将工作于同一事务上下文中。但是 使用 Spring JDBC 访问数据时,Hibernate 的一级或二级缓存得不到同步,此外,一级缓存延 迟数据同步机制可能会覆盖 Spring JDBC 数据更改的结果。

由于混合数据访问技术的 方案的事务同步而缓存不同步的情况,所以最好用 Hibernate 完成读写操作,而用 Spring JDBC 完成读的操作。如用 Spring JDBC 进行简要列表的查询,而用 Hibernate 对查询出的数 据进行维护。如果确实要同时使用 Hibernate 和 Spring JDBC 读写数据,则必须充分考虑到 Hibernate 缓存机制引发的问题:必须充分分析数据维护逻辑,根据需要,及时调用 Hibernate 的 flush() 方法,以免覆盖 Spring JDBC 的更改,在 Spring JDBC 更改数据库时 ,维护 Hibernate 的缓存。

可以将以上结论推广到其它混合数据访问技术的方案中, 如 Hibernate+iBatis,JPA+Spring JDBC,JDO+Spring JDBC 等。

特殊方法成漏网之鱼

由于 Spring 事务管理是基于接口代理或动态字节码技术,通过 AOP 实施事务增强的 。虽然,Spring 还支持 AspectJ LTW 在类加载期实施增强,但这种方法很少使用,所以我们 不予关注。

对于基于接口动态代理的 AOP 事务增强来说,由于接口的方法是 public 的,这就要求实现类的实现方法必须是 public 的(不能是 protected,private 等),同时 不能使用 static 的修饰符。所以,可以实施接口动态代理的方法只能是使用 “public”或“public final”修饰符的方法,其它方法不可能被动态 代理,相应的也就不能实施 AOP 增强,也不能进行 Spring 事务增强了。

基于 CGLib 字节码动态代理的方案是通过扩展被增强类,动态创建子类的方式进行 AOP 增强植入的。由于 使用 final、static、private 修饰符的方法都不能被子类覆盖,相应的,这些方法将不能被 实施 AOP 增强。所以,必须特别注意这些修饰符的使用,以免不小心成为事务管理的漏网之鱼 。

下面通过具体的实例说明基于 CGLib 字节码动态代理无法享受 Spring AOP 事务增 强的特殊方法。

清单 6.UserService.java:4 个不同修饰符的方法

package user.special; import  org.springframework.stereotype.Service; @Service("userService") public class UserService {  //① private方法因访问权限的限制,无 法被子类覆盖   private void method1() {     System.out.println ("method1");   }  //② final方法无法被子类覆盖   public  final void method2() {     System.out.println("method2"

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站: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号