当外部事务回滚时,Propagation.REQUIRES_NEW
和 Propagation.NESTED
的行为有显著不同:
-
Propagation.REQUIRES_NEW:
- 独立性:
REQUIRES_NEW
启动一个完全独立的新事务。因此,即使外部事务回滚,REQUIRES_NEW
创建的内部事务也不会受到影响。如果内部事务已经成功提交,它的结果将保持不变,不会因为外部事务的回滚而被撤销。 - 应用场景: 适用于需要确保某些操作无论外部事务的结果如何都必须提交的情况。例如,记录日志或发送通知等操作。
- 独立性:
-
Propagation.NESTED:
- 依赖性:
NESTED
在外部事务的上下文中创建一个嵌套事务(通过保存点实现)。如果外部事务回滚,嵌套事务的所有操作也会被回滚,因为它们是外部事务的一部分。 - 部分回滚:
NESTED
的主要优势在于允许在外部事务中进行部分回滚。如果嵌套事务本身失败,可以回滚到它的保存点,而不影响整个外部事务的其他部分。 - 应用场景: 适用于需要在一个大事务中对某些操作进行独立控制的情况,允许在失败时回滚到某个中间状态。
- 依赖性:
-
REQUIRED:
- 默认行为: 如果当前有事务在运行,方法将在该事务中执行。否则,会启动一个新的事务。
- 常用场景: 适用于大多数情况,因为它能有效地重用现有事务。
-
SUPPORTS:
- 支持事务: 如果当前有事务在运行,方法将在该事务中执行。如果没有事务,方法将以非事务方式执行。
- 常用场景: 适用于既能在事务中执行,也能在非事务中执行的操作。
-
MANDATORY:
- 必须存在事务: 方法必须在现有事务中执行。如果没有活动事务,会抛出异常。
- 常用场景: 适用于必须在事务上下文中执行的操作。
-
REQUIRES_NEW:
- 新事务: 每次调用方法时,都会启动一个新的事务。如果当前有事务在运行,Spring 会暂停当前事务。
- 常用场景: 适用于需要独立提交或回滚的操作。
-
NOT_SUPPORTED:
- 非事务方式: 方法不应在事务中执行。如果当前有事务在运行,Spring 会暂停该事务。
- 常用场景: 适用于不需要事务支持的操作。
-
NEVER:
- 禁止事务: 方法必须在非事务上下文中执行。如果当前有事务在运行,会抛出异常。
- 常用场景: 适用于明确不希望在事务中执行的操作。
-
NESTED:
- 嵌套事务: 如果当前有事务在运行,方法将在该事务中创建一个嵌套事务(使用保存点)。如果没有事务,行为类似于
REQUIRED
。 - 常用场景: 适用于需要部分回滚的场景。
- 嵌套事务: 如果当前有事务在运行,方法将在该事务中创建一个嵌套事务(使用保存点)。如果没有事务,行为类似于