springboot事务中的一些坑

springboot开启声明式事务方式

  • 在Application启动类中加入注解@EnableTransactionManagement(mode = AdviceMode.PROXY)
  • 在需要加入事务的方法上加入注解@Transactional
  • @Transactional(rollbackFor = RollbackException.class) 抛出指定异常时回滚
    /**
     * 

* (rollbackFor = RollbackException.class) 抛出自定义异常时,回滚事务。 *

* @throws RollbackException */ @Override @Transactional(rollbackFor = RollbackException.class) public void insertThenRollback() throws RollbackException { jdbcTemplate.execute("INSERT INTO Student (NAME) VALUES ('Tom')"); throw new RollbackException(); }

常见问题

例如有这个实现类StudentServiceImpl:

@Component
public class StudentServiceImpl implements StudentService {

    /**
     * 

* (rollbackFor = RollbackException.class) 抛出自定义异常时,回滚事务。 *

* @throws RollbackException */ @Override @Transactional(rollbackFor = RollbackException.class) public void insertThenRollback() throws RollbackException { jdbcTemplate.execute("INSERT INTO Student (NAME) VALUES ('BBB')"); throw new RollbackException(); } /** *

* spring的事务是通过aop进行代理增强的。 * 这里是在类的内部直接执行方法调用,并没有调用代理类来进行方法调用,所以这里事务不会回滚。 *

* * @throws RollbackException */ @Override public void invokeInsertThenRollback1() throws RollbackException { insertThenRollback(); } }

上面的insertThenRollback()回回滚事务,invokeInsertThenRollback1()调用了insertThenRollback()方法但是不会回滚事务,这是为什么呢?
这是因为spring的事务是通过aop进行代理增强的,但这里是在类的内部直接执行方法调用,并没有调用代理类来进行方法调用,所以这里事务不会回滚。

解决办法

  • 第一种方法:通过AopContext.currentProxy()获取当前类的代理对象。
    /**
     *
     * 通过AopContext.currentProxy()获取当前类的代理对象
     *
     * @throws RollbackException
     */
    @Override
    public void invokeInsertThenRollback2() throws RollbackException {
        ((StudentService) (AopContext.currentProxy())).insertThenRollback();
    }
  • 第二种方法:把自己的实例注入进来,让spring为我们创建代理。
    //把自己的实例注入进来
    @Autowired
    private StudentService studentService;
    
    
    /**
     * 把自己的实例注入进来
     * @throws RollbackException
     */
    @Override
    public void invokeInsertThenRollback3() throws RollbackException {
        studentService.insertThenRollback();
    }

你可能感兴趣的:(springboot事务中的一些坑)