Spring事务注解Transactional失效

前情提要:当Service接口实现类中存在内部方法调用,并且方法需要支持事务控制时,事务控制失效,事务的传播级别为默认REQUIRED(默认模式)。

1、简化版翻车代码:

那些年趟过的坑三——Spring事务注解Transactional失效

Service接口层

那些年趟过的坑三——Spring事务注解Transactional失效

Service接口实现类

2、需求说明:

(1)数据库表主要有两个,t_user(用户表),t_sms(发送短信记录表);

(2)主业务为新用户注册,往数据库中添加用户记录,t_user表中有记录存在,后面的其他操作不应该影响此操作(方法有事务);

(3)辅助功能(方法有事务),先往t_sms表中记录短信内容,再调API网关服务,向用户发送注册成功短信提醒,如果API网关服务调用成功,则t_sms表中有记录,如查API网关服务调用失败,则t_sms表中无记录(事务回滚)

3、结果:

当辅助功能方法发生异常时,该方法的事务控制失效,两张表中都会有记录存在,没达到预期的效果。

4、@Transactional失效原因分析:

在应用系统调用声明@Transactional 的目标方法时,Spring Framework 默认使用 AOP 代理,在代码运行时生成一个代理对象,再由这个代理对象来统一管理,当在Service实现类直接调用内部方法时,其本质是通过this对象来调用的方法,而不是代理对象,因为会出现事务失效的情况

5、解决方法:

显示的通过代理对象来调用方法:

UserService currentProxy = (UserService) AopContext.currentProxy();

currentProxy.addSms(user);

那些年趟过的坑三——Spring事务注解Transactional失效

如果如上操作还生效,则在在Spring配置文件中加入<aop:aspectj-autoproxy proxy-target-class="true" expose-proxy="true"/>暴露代理对象,同时引入aspectj 和cglib相关jar包

6、总结——注解方式的事务使用注意事项:

(1)正确的设置@Transactional 的 propagation 属性

(2)正确的设置@Transactional 的 rollbackFor 属性

(3)@Transactional 只能应用到 public 方法才有效

(4)遇到方法自调用问题,显示通代理对象调用


  • 5
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值