33. 什么是Spring中的事务传播行为(Transaction Propagation)?
在 Spring 中,事务传播行为(Transaction Propagation)定义了在一个事务上下文中方法的执行方式。当一个方法被调用时,如果当前已经存在一个事务,事务传播行为决定该方法是加入现有的事务还是创建一个新的事务,或者以非事务方式执行。
Spring 提供了多种事务传播行为,开发者可以通过配置 @Transactional
注解的 propagation
属性来控制事务的传播行为。以下是 Spring 中常见的事务传播行为及其含义:
1. REQUIRED(默认)
描述:如果当前没有事务,则创建一个新事务;如果当前已经存在一个事务,则加入该事务。
应用场景:这是最常用的传播行为,适用于大多数情况。默认情况下,Spring 事务管理器会使用这个传播行为。
示例:
@Transactional(propagation = Propagation.REQUIRED) public void someMethod() { // 业务逻辑 }
在这个例子中,如果
someMethod
在调用时已经处于一个事务中,那么它会加入该事务;如果没有事务,Spring 会创建一个新的事务。
2. REQUIRES_NEW
描述:无论当前是否存在事务,都会创建一个新的事务。如果当前存在事务,则暂时挂起当前事务,直到新事务完成。
应用场景:适用于需要独立提交或回滚的操作,即使当前存在事务,也希望这个方法执行时不受外部事务的影响。
示例:
@Transactional(propagation = Propagation.REQUIRES_NEW) public void someMethod() { // 业务逻辑 }
在这个例子中,
someMethod
总是运行在一个新事务中,原有的事务(如果存在)会在此方法执行期间被挂起。
3. MANDATORY
描述:必须在一个现有事务中执行,如果当前没有事务,则抛出异常。
应用场景:适用于必须有事务存在的情况下执行的方法,如果调用此方法时没有事务存在,通常意味着调用者的逻辑有问题。
示例:
@Transactional(propagation = Propagation.MANDATORY) public void someMethod() { // 业务逻辑 }
在这个例子中,如果调用
someMethod
时没有事务上下文存在,Spring 将抛出异常。
4. SUPPORTS
描述:如果当前存在事务,则方法在事务中执行;如果没有事务存在,则以非事务方式执行。
应用场景:适用于既可以在事务中执行,也可以不需要事务执行的方法。事务存在时,方法将加入事务;否则,它将以非事务方式执行。
示例:
@Transactional(propagation = Propagation.SUPPORTS) public void someMethod() { // 业务逻辑 }
在这个例子中,
someMethod
会根据上下文决定是否使用事务。
5. NOT_SUPPORTED
描述:方法总是以非事务方式执行。如果当前有事务存在,则挂起该事务,直到方法执行完毕。
应用场景:适用于不希望方法在事务中执行的场景,避免事务对该方法的影响。
示例:
@Transactional(propagation = Propagation.NOT_SUPPORTED) public void someMethod() { // 业务逻辑 }
在这个例子中,
someMethod
会以非事务方式执行,即使在调用它时存在事务。
6. NEVER
描述:方法总是以非事务方式执行。如果当前存在事务,则抛出异常。
应用场景:适用于明确不允许在事务中执行的方法。如果该方法在事务上下文中调用,将抛出异常。
示例:
@Transactional(propagation = Propagation.NEVER) public void someMethod() { // 业务逻辑 }
在这个例子中,
someMethod
只有在没有事务的情况下才能执行,否则会抛出异常。
7. NESTED
描述:如果当前存在事务,则在嵌套事务中执行方法。嵌套事务可以单独回滚,而不影响外部事务。如果当前没有事务,则与
REQUIRED
行为相同,创建一个新的事务。应用场景:适用于希望在一个事务中执行部分操作,并且这些操作可以在不影响外部事务的情况下回滚。
示例:
@Transactional(propagation = Propagation.NESTED) public void someMethod() { // 业务逻辑 }
在这个例子中,
someMethod
在嵌套事务中执行,嵌套事务的回滚不会影响外部事务。
8. 总结
- Propagation.REQUIRED 是最常用的事务传播行为,适用于大多数事务管理需求。
- Propagation.REQUIRES_NEW 适用于需要创建独立事务的场景,通常用于日志记录、补偿等需要与主事务隔离的操作。
- Propagation.NESTED 提供了更细粒度的事务控制,允许在一个大事务中执行部分回滚。
事务传播行为为开发者提供了灵活的事务管理策略,确保应用程序能够根据不同的业务需求正确处理事务的边界和行为。