分析动态代理给Spring事务埋下的坑
前言
Spring的声明式事务让我们不在编写获得连接、关闭连接、开启事务、提交事务、回滚事务等代码,通过一个简单的@Transactional注解,就让我们轻松进行事务处理。我们知道Spring事务基于AOP,采用动态代理实现,虽然使用简单,但是在实际场景中,我们也会遇到一些坑。而往往遇到坑之后,我们都会茫然,这是由于没有对Spring事务的实现机制做一点了解导致的。因此本篇博客将从原理的角度分析下动态代理给Spring事务埋下的坑!
从动态代理到Spring事务
UserService:
txMethod和txMethod2方法模拟事务方法(相当于@Transactional)
noTxMethod方法是普通方法
UserServiceImpl
在Spring事务中,我们往往是在Service层进行事务控制。
我们在UserServiceImpl中想模拟的是:
一个有事务的方法,去调用另一个有事务的方法,会怎么样?
一个没有事务的方法,去调用一个有事务的方法,会怎么样?
UserHandler
这里为了简便,通过方法名称来判断是否开启事务。
显然,txMethod方法、txMethod2方法都“应该”开启事务。
UserTest
下面,我们来说下运行结果:
proxyInstance.txMethod2()方法,会开启事务,这没有问题。
proxyInstance.txMethod()方法,虽然在事务方法txMethod()内部调用了txMethod2()事务方法,但是并没有新开启事务。
proxyInstance.noTxMethod()方法,虽然在没有事务的方法noTxMethod()内部调用了有事务的txMethod2()方法,但是并没有开启事务。
下面让我们来对应下Spring事务中的现象:
上述的情况,说白了,就是在一个Service内部,事务方法之间的嵌套调用,普通方法和事务方法之间的嵌套调用,都不会开启新的事务!
为什么会这样呢?
其实通过上面的动态代理的代码,你应该可以发现:
动态代理最终都是要调用原始对象的,而原始对象在去调用方法时,是不会再触发代理了!
那么如何解决呢?
很简单,我们完全可以在抽出一个XxxService,在其内部调用UserService.txMethod()和UserService.txMethod2()方法即可。总而言之,避免在一个Service内部进行事务方法的嵌套调用!(因为动态代理导致这种场景事务失效了。)
好像Spring事务如此简单,但是背后却有这些道道,你被坑过么?

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
总结一下:运维工程师面试的经历及面试相关问题(续2)
在上一篇文章总结一下:运维工程师面试的经历及面试相关问题(会持续更新)笔者也讲到会持续更新,由于上一篇文章内容有点长,为了便于大家阅读,所以笔者就另起这篇文章继续来讲述一下笔者的其它面试过程的面试问题。 其实笔者写这文章的目的很简单,就是想和大家一起探讨和学习咋们做运维的兄弟如何在面试的时候成功率能大幅度的提高,并且能拿到满意的待遇,当然自身还是要不断的学习,提高技术能力。还有就是大家去面试前看一下这篇文章对面试会有所帮助,面试的时候能更加的自信,笔者也想多交些朋友,共同学习和进步。下面分享一下笔者在2018年1月8号和海外面试官司的电话面试是怎么进行的? 2018年1月8号海外电话面试 一次偶然的机会,笔者在一个招聘平台中(我就不细说哪个平台,免得有打广告的意思)刷新岗位的时候突然看到一个新发布的岗位,仔细一看是海外的岗位,上面写的待遇、福利、工作内容笔者都有点兴趣,由于笔者也没有尝试过海外面试的机会和感觉,所以就和发布这个岗位的猎头联系上了。 猎头问我要了简历,并把个人信息详细丰富了一下,比如有没有护照、工作了多久、个人职业规划、期望到手的薪资等等。猎头就把我的简历和详细的个人信息...
- 下一篇
PoW挖矿算法原理及其在比特币、以太坊中的实现
PoW,全称Proof of Work,即工作量证明,又称挖矿。大部分公有链或虚拟货币,如比特币、以太坊,均基于PoW算法,来实现其共识机制。即根据挖矿贡献的有效工作,来决定货币的分配。 比特币区块 比特币区块由区块头和该区块所包含的交易列表组成。区块头大小为80字节,其构成包括: 4字节:版本号32字节:上一个区块的哈希值32字节:交易列表的Merkle根哈希值 4字节:当前时间戳 4字节:当前难度值 4字节:随机数Nonce值此80字节长度的区块头,即为比特币Pow算法的输入字符串。交易列表附加在区块头之后,其中第一笔交易为矿工获得奖励和手续费的特殊交易。bitcoin-0.15.1源码中区块头和区块定义: class CBlockHeader { public: //版本号 int32_t nVersion; //上一个区块的哈希值 uint256 hashPrevBlock; //交易列表的Merkle根哈希值 uint256 hashMerkleRoot; //当前时间戳 uint32_t nTime; //当前挖矿难度,nBits越小难度越大 uint32_t nBits;...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS6,CentOS7官方镜像安装Oracle11G
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS7设置SWAP分区,小内存服务器的救世主
- CentOS8安装Docker,最新的服务器搭配容器使用
- Hadoop3单机部署,实现最简伪集群