详细:
在方法上添加@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配置错误:如切点表达式不匹配
除此之外, 还能导致事务失效的情况有:
-
异常没有被抛出
@Transactional
默认只在遇到RuntimeException
和Error
时回滚。如果方法捕获了异常并且没有重新抛出,事务不会回滚。-
事务的属性配置错误
-
Propagation.NOT_SUPPORTED
会挂起当前事务。 Propagation.NEVER
会在存在事务时抛出异常。-
数据库或表不支持事务
-
Spring 事务是对数据库事务的封装和增强, 底层实现完全依赖于数据库的事务支持。无论是单数据源还是多数据源,Spring最终都是通过调用数据库的事务API(如 JDBC 的
Connection
、 JPA 的EntityManager
等)来开启、提交或回滚事务。 - 事务管理器和数据源配置有误
-
方法中使用了非事务性操作
- 如文件操作、网络请求等, 这些操作不会受到事务管理
相关文章
暂无评论...