100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > 【Java|sql|事务异常】Transaction rolled back because it has been marked as rollback-only

【Java|sql|事务异常】Transaction rolled back because it has been marked as rollback-only

时间:2024-01-05 03:08:11

相关推荐

【Java|sql|事务异常】Transaction rolled back because it has been marked as rollback-only

问题:

methodA方法的异常被methodB方法捕获捕获,但并未抛出,事务仅被标记rollback,而事务继续提交,最后事务提交校验时抛出Transaction rolled back because it has been marked as rollback-only异常。注意:此时内层事务和外层事务为同一事务。

@Transactional(rollbackFor = Exception.class)public void methodA(){insert();System.out.println(1 / 0);}@Transactional(rollbackFor = Exception.class)public void methodB(){try{methodA();}catch(Exception e){System.out.println("有异常");}}

解释:

当spring开启事务时,如果不修改propagation的参数,则默认是propagation.REQUIRED。即如果有没有事务则新启一个事务,如果已经存在事务则加入这个事务。

当内层事务异常的情况下,如果是这种传播方式,正常来讲是需要回滚的,但是spring只是给内层事务做了一个rollback的标记。所以当内层事务抛出的异常被外层try-----catch捕获(未抛出)时,外层事务正常执行,但在最后提交的时候发现,内层被标记了rollbck,所以就会抛出Transaction rolled back because it has been marked as rollback-only这个异常信息。

解决方案

如果我们需要内层异常的情况下,回滚整个事务,可以让内层事务抛出的异常被外层事务的try----catch处理,再抛出新的异常,或者外层不通过try—catch处理这个异常。

@Transactional(rollbackFor = Exception.class)public void methodA(){System.out.println(1 / 0);}@Transactional(rollbackFor = Exception.class)public void methodB(){try{insert();methodA();}catch(Exception e){throw new Exception("存在异常")}}

如果内层事务异常的情况下只回滚内层事务,修改内层事务的事务传播方式(不建议)

@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)public void methodA(){System.out.println(1 / 0);}@Transactional(rollbackFor = Exception.class)public void methodB(){try{insert();methodA();}catch(Exception e){System.out.println("有异常");}}

@Transactional(propagation = Propagation.REQUIRES_NEW)

@Transactionalpublic CommonReturnType funA() {//...funB(); // 调用函数B//...func(); // 调用函数C//...}@Transactional(propagation = Propagation.REQUIRES_NEW)public void funB() {//...}@Transactional(propagation = Propagation.REQUIRES)public void funC() {//...}

Spring遇到嵌套事务时,当被嵌套的事务被定义为“PROPAGATION_REQUIRES_NEW”时,

内层Service的方法被调用时,外层方法的事务被挂起;

内层事务相对于外层事务是完全独立的,有独立的隔离性;

新的执行完毕,继续执行老的事务

当出现异常时:

1、当方法B或者C报错时,A、B、C方法都回滚

2、当方法A、B、C异常被捕获时,A、B、C事务不回滚(a、b、c均入库)

3、当方法BC执行后,方法A报错时,A、C事务回滚,B事务不回滚(b数据入库)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。