SpringBoot内部调用事务不起作用问题的解决方案

作者:平头哥的技术博文 时间:2023-11-17 13:38:35 

在做业务开发时,遇到了一个事务不起作用的问题。大概流程是这样的,方法内部的定时任务调用了一个带事务的方法,失败后事务没有回滚。查阅资料后,问题得到解决,记录下来分享给大家。

场景

我在这里模拟一个场景,大概的调用方式就如下面的代码这样。


 @Override
 @Transactional(rollbackFor = RuntimeException.class)
 public void insertUser(User user) {
   userMapper.insertUser(user);
   throw new RuntimeException("");
 }

/**
  * 内部调用新增方法
  *
  * @param user
  */
 @Override
 public void invokeInsertUser(User user) {
   this.insertUser(user);
 }

原因

AOP使用的是 * 的机制,它会给类生成一个代理类,事务的相关操作都在代理类上完成。内部方式使用this调用方式时,使用的是实例调用,并没有通过代理类调用方法,所以会导致事务失效。

解决办法

方法一 引入自身bean

在类内部通过@Autowired将本身bean引入,然后通过调用自身bean,从而实现使用AOP代理操作。

注入自身bean


 @Autowired
 @Lazy
 private UserService service;

修改invokeInsertUser方法


 /**
  * 解决方法一 在bean中将自己注入进来
  * @param user
  */
 @Override
 public void invokeInsertUser(User user) {
   this.service.insertUser(user);
 }

方法二 通过ApplicationContext引入bean

通过ApplicationContext获取bean,通过bean调用内部方法,就使用了bean的代理类。

注入ApplicationContext


 @Autowired
 ApplicationContext applicationContext;

修改invokeInsertUser方法


 /**
  * 解决方法二 通过applicationContext获取到bean
  * @param user
  */
 @Override
 public void invokeInsertUser(User user) {
   ((UserService)applicationContext.getBean("userService")).invokeInsertUser(user);
 }

方法三 通过AopContext获取当前类的代理类

通过AopContext获取当前类的代理类,直接通过代理类调用方法

在引导类上添加@EnableAspectJAutoProxy(exposeProxy=true)注解

修改invokeInsertUser方法


 /**
  * 解决方法三 通过applicationContext获取到bean
  *
  * @param user
  */
 @Override
 public void invokeInsertUser(User user) {
   ((UserService) AopContext.currentProxy()).invokeInsertUser(user);
 }

来源:https://www.cnblogs.com/jamaler/p/11398149.html

标签:springboot,内部,调用,事务
0
投稿

猜你喜欢

  • spring @schedule注解如何动态配置时间间隔

    2023-07-29 03:51:14
  • Android自定义控件实现圆形进度条

    2023-02-02 05:01:59
  • 详解Mybatis是如何解析配置文件的

    2023-10-15 23:23:40
  • Android通过访问网页查看网页源码实例详解

    2023-10-05 03:09:11
  • Android结束进程的方法详解

    2023-06-09 20:27:30
  • Android编程解析XML方法详解(SAX,DOM与PULL)

    2022-12-07 16:03:46
  • Java封装的实现访问限定符、包

    2023-03-20 07:08:48
  • C#中怎样从指定字符串中查找并替换字符串?

    2023-09-30 14:26:24
  • springboot项目启动慢的问题排查方式

    2023-06-19 18:58:40
  • 一些比较实用的 Android adb 命令分享

    2023-12-22 12:39:41
  • Spring JPA之find拓展方法示例详解

    2021-12-11 03:50:49
  • java中synchronized锁的升级过程

    2023-12-01 13:14:51
  • Android Retrofit 2.0框架上传图片解决方案

    2022-02-23 06:25:27
  • 用C#实现启动另一程序的方法实例

    2023-06-20 12:05:43
  • 深入谈谈C#9新特性的实际运用

    2021-05-26 16:08:23
  • unity 实现摄像机绕某点旋转一周

    2021-06-11 16:48:57
  • c#中使用BackgroundWorker的实现

    2023-05-04 08:51:01
  • 如何让Spring Rest 接口中路径参数可选

    2022-02-17 19:29:14
  • Android实现打开各种文件的intent方法小结

    2022-03-12 18:39:20
  • Java单例模式实现的几种方式

    2021-06-09 18:38:47
  • asp之家 软件编程 m.aspxhome.com