本文概览:介绍下使用@Transaction常遇到问题
1 同一个类中两个@Transaction
如下一个Test 类,在doProcess()中抛异常之后,并没有事务回滚,因为对于outer()执行了try…catch吞掉了异常,所以不会触发outer()的事务回滚。而且对于doProcess函数上事务注解是无效的,这是因为在同一个类中,一个函数调用一个使用注解@Transaction的函数,第二个函数注解不会生效,注解只会生效在第一个函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
@Service class Test{ @Transactional public Response outer(Requset requset){ try{ // 参数校验 check(requset) // 调用 innner() doProcess(requset); // 返回成功response return response; }catch (Exception e){ logger.error("....."); // 返回response return response; } } @Transactional public void doProcess(Requset requset){ // 1.执行业务逻辑 // 2.抛异常 } } |
为了解决这个问题,有一个简单实现,在定义一个Process类,将doProcess移除去,此时就可以生效了,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
@Service class Test{ @Autowired private Processor processor; @Transactional public Response outer(Requset requset){ try{ // 参数校验 check(requset) // 调用 innner() processor.doProcess(requset); // 返回成功response return response; }catch (Exception e){ logger.error("....."); // 返回response return response; } } } @Service class Processor{ @Transactional public void doProcess(Requset requset){ // 1.执行业务逻辑 // 2.抛异常 } } |
还有一种更优雅的方法,在outer中使用“ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();”来使事务进行回滚,如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
@Transactional public Response outer(Requset requset){ try{ // 参数校验 check(requset) // 调用 innner() doProcess(requset); // 返回成功response return response; }catch (Exception e){ logger.error("....."); // 设置事务属性 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); // 返回response return response; } } |
(待补充)