SpringBoot中如何使用事务, 有哪些失效的情况

详细:

在方法上添加@Transactional注解来开启事务, 有多个可配置选项用于控制事务的行为

可指定的配置选项:

  • rollbackFor属性指定事务回滚的规则

    • DEFAULT:使用数据库的默认隔离级别。
    • READ_UNCOMMITTED:允许读取未提交的数据。
    • READ_COMMITTED:只能读取已提交的数据。
    • REPEATABLE_READ:确保在同一事务中多次读取相同数据时结果一致。
    • SERIALIZABLE:最高隔离级别,确保事务串行执行。
    • isolation指定事务的隔离级别

    • DEFAULT:使用数据库的默认隔离级别。

    • READ_UNCOMMITTED:允许读取未提交的数据。
    • READ_COMMITTED:只能读取已提交的数据。
    • REPEATABLE_READ:确保在同一事务中多次读取相同数据时结果一致。
    • SERIALIZABLE:最高隔离级别,确保事务串行执行。
    • propagation指定事务的传播行为

    • REQUIRED(默认):如果当前存在事务,则加入该事务;如果不存在,则创建一个新事务。

    • REQUIRES_NEW:总是创建一个新事务,如果当前存在事务,则挂起当前事务。
    • SUPPORTS:如果当前存在事务,则加入该事务;如果不存在,则以非事务方式执行。
    • NOT_SUPPORTED:以非事务方式执行,如果当前存在事务,则挂起当前事务。
    • MANDATORY:如果当前存在事务,则加入该事务;如果不存在,则抛出异常。
    • NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
    • NESTED:如果当前存在事务,则在嵌套事务中执行;如果不存在,则创建一个新事务。
    • timeout定义事务的超时时间(单位:秒)。如果事务在指定时间内未完成,则自动回滚。

事务失效的情况:

由于Spring的事务管理通过AOP实现, 因此所有能够导致AOP动态代理失效的情况通常都会导致事务失效,

如:

  • 非public方法、静态方法或 final 方法:Spring AOP默认只能代理public方法,也无法代理静态方法或final方法。
  • 自调用:在同一个类 中,一个方法调用另一个带有注解的方法时,属于内部调用,不会经过代理对象,而是使用this直接调用目标方法。
  • 代理模式配置错误:Spring默认使用JDK动态代理,如果目标类没有实现接口,代理将无法生效。
  • 手动创建对象:如果通过new关键字手动创建对象,而不是通过Spring容器管理,AOP代理不会生效
  • 方法被异步调用:如果事务方法被异步调用(例如通过@Async),代理可能不会生效,因为异步方法通常在不同的线程中执行。
  • AOP配置错误:如切点表达式不匹配

除此之外, 还能导致事务失效的情况有:

  1. 异常没有被抛出

    • @Transactional默认只在遇到RuntimeExceptionError时回滚。如果方法捕获了异常并且没有重新抛出,事务不会回滚。
    • 事务的属性配置错误

    • Propagation.NOT_SUPPORTED会挂起当前事务。

    • Propagation.NEVER会在存在事务时抛出异常。
    • 数据库或表不支持事务

    • Spring 事务是对数据库事务的封装和增强, 底层实现完全依赖于数据库的事务支持。无论是单数据源还是多数据源,Spring最终都是通过调用数据库的事务API(如 JDBC 的Connection、 JPA 的EntityManager等)来开启、提交或回滚事务。

    • 事务管理器和数据源配置有误
  2. 方法中使用了非事务性操作

    • 如文件操作、网络请求等, 这些操作不会受到事务管理
版权声明:程序员胖胖胖虎阿 发表于 2024年12月31日 上午5:17。
转载请注明:SpringBoot中如何使用事务, 有哪些失效的情况 | 胖虎的工具箱-编程导航

相关文章

暂无评论

暂无评论...