Spring源码解析(一) Spring事务控制之Hibernate

本文将对Spring在整合Hibernate事务方面的源码作一下初步的解析,特别是Spring对线程、事务、Hibernate Session三者的绑定关系。(注:本文基于目前最新的Spring 3.1.2 RELEASE 版本的源码进行分析)本文原文链接http://blog.csdn.net/bluishglc/article/details/7774131 转载请注明出处。


众所周知,Spring的事务控制是基于AOP来实现的,而AOP的实现又依赖于JDK的动态代理或者是aspectj,一般情况下,遵循“基于抽象编程”的教义,Service层和DAO层都以接口+实现类的方式提供,此时,Spring会使用动代理来实现AOP拦截,我们的分析也是基于这种拦截方式展开的。那么下面,我们就假设:一个声明了事务的方法(如某个Service的方法)被调用了,在调用时,该方法将被拦截,执行拦截的方法是:


org.springframework.aop.framework.JdkDynamicAopProxy.invoke(Object, Method, Object[])


该方法主要是把所要调用的目标方法和需要施加的操作(即AOP中的Interceptor/Advice)粘合成一个ReflectiveMethodInvocation实例去执行。ReflectiveMethodInvocation最终会调用

org.springframework.transaction.interceptor.TransactionInterceptor.invoke(MethodInvocation)


进行有关事务的操作。作为一个环绕切面,该方法主要负责在目标方法执行前开始一个事务,在方法执行结束后提交事务。




我们先来深入了解一下事务是如何创建的。从方法createTransactionIfNecessary()上可以看到,创建事务的主要方法是:


org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(TransactionDefinition)


作为抽象类的方法,getTransaction()只处理了一些通用性的检查和设置,实质性的创建事务和开启事务操作都是通过分别调用抽象方法:


org.springframework.transaction.support.AbstractPlatformTransactionManager.doGetTransaction()

org.springframework.transaction.support.AbstractPlatformTransactionManager.doBegin(Object,TransactionDefinition)


来完成的,也就是说这些关键性的工作必须由各具体事务管理器来实现,对于hibernate的事务管理器来说,获取事务对象的方法如下:




开始事务的方法如下:




以上是关于事务开始部分的代码,下面我们来看一下事务提交时的代码:
同样的,从方法commitTransactionAfterReturning()我们可以看出执行事务提交的方法主要通过回调
org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(DefaultTransactionStatus)
来实现的。



补充:

关于方法
org.springframework.transaction.support.TransactionSynchronizationManager.getResource(Object key)
如该方法的注释所说,它主要是通过给定的key找到对应的资源,特别之处是这些资源实例是绑定在线程上的,也就是spring保证一个线程上一个key对应一个资源实例,不同的线程上绑定的是不同的资源实例。对应到Hibernate上来说,key是sessionFactory,资源是sessionHolder!

近期其他博文:

数据库分库分表(sharding)系列(三) 关于使用框架还是自主开发以及sharding实现层面的考量

数据库分库分表(sharding)系列(二) 全局主键生成策略

数据库分库分表(sharding)系列(一) 拆分实施策略和示例演示


17
 
0
 
 
    猜你在找
    SpringMVC Spring Hibernate框架整合视频
    Spring4&Struts2;.3&Hibernate4; 整合案例视频
    Maven+Struts2+Spring4+Hibernate4+Bootstrap客户关系系统视频
    Hibernate实战-使用SSH框架技术开发学籍管理系统
    hibernate4_基于xml和annotation两种配置方式
    Spring中的AOP面向切面编程
    Spring框架简介
    spring基础
    扩展 Spring 的 JMX 支持
    JAVA开发全集
    id="iframeu1607657_0" src="http://pos.baidu.com/tcqm?sz=728x90&rdid=1607657&dc=2&di=u1607657&dri=0&dis=0&dai=2&ps=4541x305&coa=at%3D3%26rsi0%3D728%26rsi1%3D90%26pat%3D6%26tn%3DbaiduCustNativeAD%26rss1%3D%2523FFFFFF%26conBW%3D1%26adp%3D1%26ptt%3D0%26titFF%3D%2525E5%2525BE%2525AE%2525E8%2525BD%2525AF%2525E9%25259B%252585%2525E9%2525BB%252591%26titFS%3D%26rss2%3D%2523000000%26titSU%3D0%26ptbg%3D90%26piw%3D0%26pih%3D0%26ptp%3D0&dcb=BAIDU_SSP_define&dtm=HTML_POST&dvi=0.0&dci=-1&dpt=none&tsr=0&tpr=1468996364421&ti=Spring%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90(%E4%B8%80)%20Spring%E4%BA%8B%E5%8A%A1%E6%8E%A7%E5%88%B6%E4%B9%8BHibernate%20-%20Laurence%E7%9A%84%E6%8A%80%E6%9C%AF%E5%8D%9A%E5%AE%A2%20-%20%E5%8D%9A%E5%AE%A2%E9%A2%91%E9%81%93%20-%20&ari=2&dbv=2&drs=3&pcs=1266x589&pss=1266x6221&cfv=0&cpl=22&chi=1&cce=true&cec=UTF-8&tlm=1468996364&rw=590&ltu=http%3A%2F%2Fblog.csdn.net%2Fbluishglc%2Farticle%2Fdetails%2F7774131&ltr=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DCRk7dyu8Hbfwaab40_6xkBzrzKM1uATiZ_Px8gJe7CnqYaZJc5gHTi5nbrrcH5vw65h5OWJrEqL9L2Eu0DI2Na%26wd%3D%26eqid%3Dd9c8d3d000016d4000000004578f1aea&ecd=1&psr=1600x900&par=1600x860&pis=-1x-1&ccd=24&cja=true&cmi=41&col=zh-CN&cdo=-1&tcn=1468996364&qn=03258501497818be&tt=1468996364404.21.78.79" width="728" height="90" align="center,center" vspace="0" hspace="0" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" allowtransparency="true" style="border-width: 0px; border-style: initial; vertical-align: bottom; margin: 0px;">
    查看评论
    7楼  DIrtyG2015-11-02 14:10发表 [回复]
    太厉害
    6楼  Naruto42013-11-16 11:40发表 [回复]
    一直有个疑问,今天遇到大神了。想问一下,在声明式事务中为什么@Transactional注解打在Controller层的方法上不起作用啊?
    Re:  line_lin2014-03-06 21:56发表 [回复]
    回复Naruto4:这个是可以有的,如果你确定你的事务管理的配置对了的话,那么看下你的controller的方法的修饰符是不是public的,文档里说如果不是public的话,那么@Transactional标签是不报错也不起作用的。
    Method visibility and @Transactional
    When using proxies, you should apply the @Transactional annotation only to methods with
    public visibility. If you do annotate protected, private or package-visible methods with the
    @Transactional annotation, no error is raised, but the annotated method does not exhibit the
    configured transactional settings. Consider the use of AspectJ (see below) if you need to annotate
    non-public methods.
    5楼  做人厚道2013-09-19 18:04发表 [回复]
    藏起来慢慢消化。
    4楼  IFULEYOU492013-04-11 16:56发表 [回复]
    为啥还要一个conncectionHolder呢
    3楼  miligu2012-08-01 22:43发表 [回复] [引用] [举报]
    藏起来慢慢看。。。
    2楼  manaduona1232012-07-26 11:51发表 [回复]
    讲得太深奥了,搞得我以为是翻译过来的文章
    1楼  -_-快乐2012-07-24 15:46发表 [回复]
    不错
    • 0
      点赞
    • 0
      收藏
      觉得还不错? 一键收藏
    • 0
      评论
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值