spring事务管理器的源码和理解

来源:互联网 发布:玛格丽特小镇 知乎 编辑:程序博客网 时间:2024/06/09 15:39

以前说了大多的原理,今天来说下spring的事务管理器的实现过程,顺带源码干货带上。

其实这个文章唯一的就是带着看看代码,但是前提你要懂得动态代理以及字节码增强方面的知识(http://blog.csdn.net/xieyuooo/article/details/7624146),关于annotation在文章:http://blog.csdn.net/xieyuooo/article/details/8002321

也有说明,所以本文也就带着看看代码而已。

关于annotation这里就不说了,我们看看平时一般会怎么样来配置spring的配置,通过配置文件反射源码如何看看。

一般来讲首先会配置一个datasource,至于你配置什么连接池还是用JNDI这里就不提到细节,总之我们认为配置的spring的全局名称为dataSource就可以了。


接下来会将datasource交给各种连接池的操作类,如:ibatis、jdbcTemplate等等,这些不是我们关心的重点,我们需要关心的是dataSource是谁来管理了,在spring中配置了给一个DataSourceTransactionManager的对象:

 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">    <property name="dataSource">     <ref bean="dataSource" />    </property></bean>

ok,先记录下来,至于下面的NameMatchTransactionAttributeSource描述了那些情况要进行事务管理,我们将它理解为一种属性配置,在运行时需要解析即可,所以他也并不是我们特别需要的重点。


接下里看看:TransactionInterceptor,它看起来有点像拦截器了,他将transactionManager包装进去了;

<bean id="txInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">  <property name="transactionManager">    <ref bean="transactionManager"/>  </property>  <property name="transactionAttributeSource">    <ref bean="txAttributes"/>  </property></bean>

这里是一个点,再继续看,BeanNameAutoProxyCreator,这个看名字就知道是自动代理的类了,并且包装了TransactionInterceptor的对象进去,也就是这个地方就是代理,然后会将事务的处理交给TransactionInterceptor拦截器来完成,可能这个不是我们的重点,不过简单看看也无妨,这个类细节代码就不贴了,进去你会看到就是讲拦截器包装后,然后通过beanName设置哪些类需要被拦截,根据你的配置来完成,spring 后来基于annotation实现的就不是这样,他会扫描类中的annotation来实现类似的功能。

一起来简单看看TransactionInterceptor吧:


细节代码太多,看关键代码,红色部分表示出来了,其实在AOP调用中,我们比较关注invoke、intercept这类代码关联字的方法,因为proxy调用的就是他们,由他们自己去调用其他的方法,这里invoke首先发现在事务下,首先调用了createTranscationIfNecessary这个方法。


跟踪进去看看:


这里看到开始获取TransactionManager了,get方法没啥好看的,配置文件注入进去了,我们看看tm.getTranscation里头做了啥。

也就是跟踪到你set的那个TranscationManager里头去了,PlatformTransactionManager有多个实现类,注意选择自己实现的那部分:本程序中叫:DataSourceTransactionManager,跟踪进去看看getTransaction方法

这个代理类,需要注意几个加红色的地方:

1、目前看来应该是获事务的方法

2、部分如果发现事务对象获取到就直接返回

3、做一个doBegin的操作,这i类关键字一般是指切入时的预先操作,那么闲看看这个doBegin干啥了


我们想要的东西来了,相信看到第二个红色区域部分,大家都会很熟悉自己做事务是怎么做的,发现spring也是这样做的。

将connection做了一个setAutoCommit(false);非自动提交模式,接下来就要看如何和框架结合起来了,如何让调用的时候使用到这个connection,调用方如何知道使用这个connection;

看另外两个红色的部分:

第一个红色部分可以看出是获取事务对象若为空(不是事务或已经是事务),则从datasource对象中获取一个connection,包装成一个handle,放入事务对象中(事务对象内部的包装请自己去看下)。

而第三个额部分是,如果是一个新的ConnectionHandler(其实判定的是一些状态,使用中,spring会修改handler的状态,这也是为什么spring要包装一个handler了,因为需要自定义的很多状态信息);他执行了一个

TransactionSynchronizationManager.bindResource(getDatasource() , txObject.getConnectionHolder());

这样一个操作,可见:TransactionSynchronizationManager提供了一个静态方法getDatasource(),看名称是绑定的意思,那么绑定什么呢?我们跟踪进去看看:


咦,resouces貌似里面有一个map,如果为空,就put一个进去,那么resouce是个什么东西呢?他会不会有线程冲突的问题?

看看resouces是什么:


ThreadLocal,对了,就是它了,有关ThreadLocal的原理和细节,我这不想多提,也不是这里的重点,这里明确的就是,虽然它是全局的一个静态属性,不过他是线程安全的,不论是get还是set还是remove。


我们知道这个connection被绑定到当前运行的线程中了,接下来只需要在使用时从这个里面获取出来即可。

我们再回到上面看到的doTransaction方法还没看细节,这里来看看。


可以看到,它果然是从这里来获取保存到当前线程的connection。


貌似看得差不多了,好像少了一半,那一半,datasouces是各个厂家的,他们的各自的datasouce方法是自己的,getConnection内部有自己的算法,如何做到他们在getConnection的时候,执行相应的,这个时候,我们来看看一个拦截connection的方式:TransactionAwareDataSourceProxy,

他内部有啥道理所在:


这里可以看到使用了动态代理,获取相应的datasouces,那么就找到对应的代理类里面去看看他的invoke方法是什么:

TransactionAwareInvocationHandler里面,可以跟踪这个是一个内部类了,进去看看他的invoke方法:



可以看到切入的位置,向上看到两个红色部分是要去获取connection,我们跟踪进去看看:


接下来的就不用多说了吧,回到刚才的代码,不论是doGetConnection还是doReleaseConnection内部都会调用

TransactionSynchronizationManager.getResource(datasouce)

来获取当前线程的connection。

当然各种连接操作对象也会有自己的transaction操作,他们也会去做setAutoCommit等相应的操作。不过最外层设置后,getConnection方法保证后,内部的操作几乎就可以跳过了。


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 新申请的qq号忘了怎么办 刚申请的qq号忘了怎么办 以前申请的qq号忘了怎么办 小孩玩手机游戏扣费了怎么办 手机qq好友头像显示不出来怎么办 qq的一些重要数据被清理怎么办 华为p9微信听筒声音小怎么办 win10我的电脑图标没了怎么办 小米5x里的微信头像不清楚怎么办 微信头像换了总是模糊怎么办 找到老公暧昧对象的微信怎么办 朋友欠我钱一直拖找借口怎么办 陌陌附近的人不按距离排序怎么办 老婆一直要管我的钱怎么办 老公不肯把钱交给老婆管怎么办 愿意和做朋友不愿意做情侣怎么办 欠信用卡碰到第三方不愿协调怎么办 qq密码忘记了申诉不回来怎么办 当你老公烦你了你该怎么办 自己有漂亮媳妇还经常想去嫖怎么办 微信号封了找不到好友解封怎么办 别人总是提起你的黑历史怎么办 换了手机微信登录不上怎么办 qq不小心清空了聊天记录怎么办 人家介绍了外地媳妇跑了怎么办 火锅想吃香菜牛肉没有签子串怎么办 想读外省大学但家人反对怎么办 13岁被同学忽视他不知道怎么办 老婆发现老公在微信暧昧聊天怎么办 老婆微信和别人聊天暧昧我该怎么办 淘宝修改标题宝贝被删了怎么办 百度网盘上的相片变的模糊怎么办 微信2不小心删了怎么办 房屋没交接前给钥匙出现问题怎么办 微信银行卡注销零钱没了怎么办 贴小广告电话被城管上报停机怎么办 没有id密码怎么办已经锁死了屏幕 电信电话卡注销了里面的钱怎么办 支付宝绑定的手机号成空号了怎么办 支付宝绑定的手机号空号了怎么办 支付宝绑定的手机号码空号了怎么办