SpringBoot 内部方法调用,事务不起作用的原因及解决办法

1.1 前言: 在做业务开发时,遇到了一个事务不起作用的问题。大概流程是这样的,在同一个类中,两个及以上带有事务的方法调用(例如;有方法A(),B(),在A()中调用B()),失败后事务没有回滚。查阅资料后,问题得到解决,记录下来分享给大家。
1.2 代码示例

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

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

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

3解决方案
3.1注入自身bean

    @Autowired
    @Lazy
    private UserService service; //用注入的此bean调用方法

   
  /**
     * 内部调用新增方法
     *
     * @param user
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void invokeInsertUser(User user) {
        service.insertUser(user);
    }

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

3.1创建一个类,把被调用的方法放在新的类里

   @Autowired
    @Lazy
    private NewPerson  newPerson;

//第一个类
public class Person{
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void invokeInsertUser(User user) {
        service.insertUser(user);
    }
}


//第二个类
public class NewPerson{
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertUser(User user) {
        userMapper.insertUser(user);
        throw new RuntimeException("");
    }
}

3.2 通过ApplicationContext引入bean


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

     @Autowired
    ApplicationContext applicationContext;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void invokeInsertUser(User user) {
        ((UserService)applicationContext.getBean("userService")).insertUser(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertUser(User user) {
        userMapper.insertUser(user);
        throw new RuntimeException("");
    }
  • 完结
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值