@Transactional注解失效的解决方案
一、前言
开发中我们经常使用 @Transactional注解来启用Spring事务管理,但是如果使用方法不当,会遇到注解不生效该事务回滚的地方却没有回滚的问题。
总结下一般是以下几个原因:
- @Transactional 注解只能应用到 public 可见度的方法上。 如果应用在protected、private或者 package可见度的方法上,也不会报错,不过事务设置不会起作用。
- 默认情况下,spring会对unchecked异常进行事务回滚;如果是checked异常则不回滚。针对这种情况,可以try catch checked异常后进行手动事务回滚。
- 数据库引擎要支持事务,如果是mysql,注意表要使用支持事务的引擎,比如InnoDB,如果是MyISAM,事务是不起作用的。
- 同一个类中, 一个no-transactional的方法去调用transactional的方法, 事务会失效。
本文主要讲第四种情况如何处理。
二、示例


执行add() 方法后数据库插入了两条数据,也就说明以上两段代码中,doAdd()方法的事务增强都不会执行,具体原因可以参考这篇文章。
那么如果想让doAdd()方法在发生异常时数据库事务回滚,有什么解决办法吗?
第一步开启配置expose-proxy
如果使用的xml配置文件的方式,则添加如下内容:
<aop:aspectj-autoproxy expose-proxy="true" />
如果用的SpringBoot框架,则直接在启动类上添加如下注解即可。
@EnableAspectJAutoProxy(proxyTargetClass = true,exposeProxy = true)
第二步修改代码
将原来的调用代码this.doAdd(person); 改为 ((PersonService)AopContext.currentProxy()).doAdd(person);

再进行测试发现数据库只插入了一条数据(person2),说明doAdd() 方法里的事务增强生效了。
三、源码分析
点进 @EnableAspectJAutoProxy 注解代码如下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
发现它注入了一个Bean AspectJAutoProxyRegistrar,再看看这个AspectJAutoProxyRegistrar是什么。
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
// 解析注解EnableAspectJAutoProxy
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
// 如果设置了exposeProxy=true就强制使用
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
AopConfigUtils#forceAutoProxyCreatorToExposeProxy
// 强制使用的过程其实也是一个属性设置的过程
public static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) {
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
definition.getPropertyValues().add("exposeProxy", Boolean.TRUE);
}
}
/**
* The bean name of the internally managed auto-proxy creator.
*/
public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
"org.springframework.aop.config.internalAutoProxyCreator";
@Transactional注解失效的解决方案的更多相关文章
- @Transactional 注解失效场景
@Transactional可以用在接口.类.类方法上. 作用于类:当把@Transactional注解放在类上时,表示该类的所有public方法都配置了该事物注解. 作用于方法:表示该方法配置了事物 ...
- @Transactional注解失效
一.特性 先来了解一下@Transactional注解事务的特性吧,可以更好排查问题 1.service类标签(一般不建议在接口上)上添加@Transactional,可以将整个类纳入spring事务 ...
- 一口气说出 6种,@Transactional注解的失效场景
整理了一些Java方面的架构.面试资料(微服务.集群.分布式.中间件等),有需要的小伙伴可以关注公众号[程序员内点事],无套路自行领取 一口气说出 9种 分布式ID生成方式,面试官有点懵了 面试总被问 ...
- @Transactional注解的失效场景
一口气说出 6种,@Transactional注解的失效场景 计算机java编程 发布时间: 20-03-1912:35优质科技领域创作者 引言 昨天公众号粉丝咨询了一个问题,说自己之前面试被问@Tr ...
- spring事务注解失效问题
问题描述: 由于工作需要,需要在spring中配置两个数据源,有一天突然发现@Transactional注解失效 环境框架: springmvc+spring+spring jdbcTemplate ...
- Spring aop注解失效
问题 在spring 中使用 @Transactional . @Cacheable 或 自定义 AOP 注解时,对象内部方法中调用该对象的其他使用aop机制的方法会失效. @Transactiona ...
- Spring @Transactional注解不起作用解决办法及原理分析
Transactional失效场景介绍 第一种 Transactional注解标注方法修饰符为非public时,@Transactional注解将会不起作用.例如以下代码. 定义一个错误的@Trans ...
- Spring中@Translational注解失效场景
今天面试被问到@Translational注解什么场景下失效,我一脸懵逼,说的恍恍惚惚的,下来我就总结一下@Translational注解失效的场景! @Transactional 注解相信大家并不陌 ...
- @Transaction注解失效的几种场景
一.@Transactional介绍 1.@Transactional注解可以作用于哪些地方? @Transactional 可以作用在接口.类.类方法上. 作用于类:表示所有该类的public方法都 ...
随机推荐
- Python中对输入的可迭代对象元素排序的sorted函数
sorted根据输入可迭代对象中的项返回一个新的已排序列表,原输入参数对象中的数据不会发生变化. 具体可参考:<Python中与迭代相关的函数>的详细介绍 老猿Python,跟老猿学Pyt ...
- PyQt(Python+Qt)学习随笔:QTreeView树形视图的headerHiden属性
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 QTreeView树形视图的headerHiden属性用于控制视图中是否隐藏标题,为True隐藏,否 ...
- 个人介绍&软工5问
个人简历: 姓名:温海源 性别:男 专业:软件工程 学校:广东工业大学 技术能力:掌握C语言 JAVA在学 证书:CET4,CET6 联系方式:1424315382@qq.com 软工5问: 1. ...
- ACM训练赛:第20次
这次的题思维都很强,等之后的考试结束会集中精力重新训练一些思维题. A - A simple question CodeForces - 520B 思路: 直接看的话,很容易发现如果 \(n > ...
- 用Ubuntu和树莓派系统部署kubernetes集群后的一些心得
方案 环境 操作系统:Ubuntu 16.04 & Raspbian GNU/Linux 9(Stretch Desktop) kubernetes :1.15.3 flannel:0.11. ...
- 数据结构与算法——循环链表的算法实现(Joseph 问题)
Joseph 问题: 如果有10 个人,按编号顺序1,2,...,10 顺时针方向围成一圈.从1 号开始顺时针方向1,2,...,9 报数,凡报数9 者出列(显然,第一个出圈为编号9 者). 最后一个 ...
- linux下/etc/profile /etc/bashrc /root/.bashrc /root/.bash_profile这四个配置文件的加载顺序
目录 一.关于linux配置文件 二.验证四个配置文件的加载顺序 三.结论 一.关于linux配置文件 1.linux下主要有四个配置文件:/etc/profile ./etc/bashrc ./ro ...
- Linux安装Mysql8.0.20并配置主从复制(一主一从,双主双从)
1. 主从复制解释 将主数据库的增删改查等操作记录到二进制日志文件中,从库接收主库日志文件,根据最后一次更新的起始位置,同步复制到从数据库中,使得主从数据库保持一致. 2. 主从复制的作用 高可用 ...
- css 01-CSS属性:字体属性和文本属性
01-CSS属性:字体属性和文本属性 #本文重要内容 CSS的单位 字体属性 文本属性 定位属性:position.float.overflow等 #CSS的单位 html中的单位只有一种,那就是像素 ...
- 这个 bug 让我更加理解 Spring 单例了
我是风筝,公众号「古时的风筝」,一个兼具深度与广度的程序员鼓励师,一个本打算写诗却写起了代码的田园码农! 文章会收录在 JavaNewBee 中,更有 Java 后端知识图谱,从小白到大牛要走的路都在 ...