美文网首页程序员
大厂数据库事务实践-事务生效就能保证正确回滚?

大厂数据库事务实践-事务生效就能保证正确回滚?

作者: JavaEdge | 来源:发表于2020-11-18 09:57 被阅读0次

AOP实现事务:使用try?c/atch包裹@Transactional注解的方法,当方法出现异常并满足一定条件时,在catch里可设置事务回滚,没有异常则直接提交事务。

“一定条件”包括:

  • 只有异常传播出了标记了@Transactional注解的方法,事务才能回滚。在Spring的TransactionAspectSupport里有个 invokeWithinTransaction方法,里面就是处理事务的逻辑。可以看到,只有捕获到异常才能进行后续事务处理:

    image
  • 默认情况下,出现RuntimeException(非受检异常)或Error,Spring才会回滚事务。

打开Spring的DefaultTransactionAttribute

  • 受检异常一般是业务异常或是类似另一种方法的返回值,出现这样的异常可能业务还能完成,所以不会主动回滚
  • 而Error或RuntimeException代表非预期结果,应回滚


    image

反面教材

注册用户:

  • createUserError1会抛RuntimeException,但方法内的catch所有异常:


    image
  • createUserError2,注册用户同时会有一次otherTask文件读,若读文件失败,希望用户注册的DB操作回滚。这里虽无捕获异常,但因otherTask抛受检异常,createUserError2传播出去的也是受检异常,事务同样不回滚:
    image
  • readFile


    image

createUserError1、2这俩方法的实现和调用,虽然避开了事务不生效的坑,但因异常处理不当,文件操作出现异常时依旧不回滚事务。

修复bug

以及如何通过日志来验证是否修复成功。针对这2种情况,对应的修复方法如下。

1 如果希望自己捕获异常并处理,可手动设置让当前事务处回滚态

@Transactional
public void createUserRight1(String name) {
    try {
        userRepository.save(new UserEntity(name));
        throw new RuntimeException("error");
    } catch (Exception ex) {
        log.error("create user failed", ex);
        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
    }
}

查看日志,事务确定回滚。

Transactional code has requested rollback:手动请求回滚。

2 在注解中声明,期望遇到所有的Exception都回滚事务

以突破默认不回滚受检异常的限制。

image

查看日志,提示回滚:
[图片上传失败...(image-cd575d-1605664603758)]

该案例有DB操作、IO操作,在IO操作问题时期望DB事务也回滚,以确保逻辑一致性。

小结

由于异常处理不正确,导致虽然事务生效,但出现异常时没回滚。
Spring默认只对被@Transactional注解的方法出现RuntimeExceptionError时回滚,所以若方法捕获了异常,就需要通过手写代码处理事务回滚。
若希望Spring针对其他异常也可回滚,可相应配置@Transactional注解的rollbackFornoRollbackFor属性覆盖Spring的默认配置。

有些业务可能包含多次DB操作,不一定希望将两次操作作为一个事务,这时就需仔细考虑事务传播的配置。

相关文章

  • 大厂数据库事务实践-事务生效就能保证正确回滚?

    AOP实现事务:使用try?c/atch包裹@Transactional注解的方法,当方法出现异常并满足一定条件时...

  • spring事务

    1、什么是事务事务和数据库操作有关,commit事务提交,rollback事务回滚事务作用:保证一组和数据库有关的...

  • laravel transaction 数据库事务

    laravel 提供专门的闭包的数据库事务,可以自动回滚事务也可以手动回滚事务

  • SpringBoot 事务回滚问题排查

    公司遇到一个问题,同样的代码不同机器打包出现事务回滚和不回滚,而每次本地调试事务均能生效。 spring事务配置 ...

  • Spring事务失效的8大原因

    一、异常被吃了 把异常吃了,然后又不抛出来,事务不会回滚。 二、异常类型错误 这样事务也是不生效的,因为默认回滚的...

  • 【Mysql】-5 事务

    事务概述 事务提交 事务回滚 事务概述 事务是只用户定义的一系列数据库更新、修改操作,这些操作要么都不执行,要么都...

  • 事务相关的问题总结

    一、事务回滚问题 二、事务失效问题 三、事务失效的解决办法 方式一:自己手动创建事务,提交事务,回滚事务(Spri...

  • 数据库_事务

    三、事务 1.什么是事务? 事务是对数据库中一系列操作进行统一的回滚或者提交的操作,主要用来保证数据的完整性和一致...

  • spring事务的传播

    前置问题 问题1:spring生成了几个逻辑事务?testTx会回滚吗? method2的事务会生效吗 ? 问题2...

  • Mysql事务&隔离级别

    数据库事务:ACID特性 原子性: 事务中所有操作要么全部提交成功,要么全部失败回滚。 u...

网友评论

    本文标题:大厂数据库事务实践-事务生效就能保证正确回滚?

    本文链接:https://www.haomeiwen.com/subject/pwiqiktx.html