在Java中,事务的传播特性定义了方法调用中事务的行为。常见的传播特性包括:
-
REQUIRED
(默认):如果当前存在事务,则加入该事务;如果没有事务,则创建一个新的事务。 -
REQUIRES_NEW
:无论当前是否存在事务,都创建一个新的事务。 -
SUPPORTS
:如果当前存在事务,则加入该事务;如果没有事务,则以非事务方式执行。 -
NOT_SUPPORTED
:以非事务方式执行,如果当前存在事务,则将其挂起。 -
MANDATORY
:必须在已有事务中执行,如果当前没有事务,则抛出异常。 -
NEVER
:以非事务方式执行,如果当前存在事务,则抛出异常。 -
NESTED
:如果当前存在事务,则在嵌套事务中执行;如果没有事务,则创建一个新的事务。
在Java中,@Transactional
注解的默认传播特性是 REQUIRED
。
传播特性排列组合场景
场景1:a
方法和 b
方法都使用 REQUIRED
-
a
方法:创建一个新的事务。 -
b
方法:加入a
方法的事务。
异常情况:
-
a
方法发生异常:b
方法的操作会回滚,因为它们在同一个事务中。 -
b
方法发生异常:a
方法的操作会回滚,因为它们在同一个事务中。
场景2:a
方法使用 REQUIRED
,b
方法使用 REQUIRES_NEW
-
a
方法:创建一个新的事务。 -
b
方法:创建一个新的事务,挂起a
方法的事务。
异常情况:
-
a
方法发生异常:b
方法的操作不会回滚,因为它们在不同的事务中。 -
b
方法发生异常:a
方法的操作不会回滚,因为它们在不同的事务中。
场景3:a
方法使用 REQUIRED
,b
方法使用 SUPPORTS
-
a
方法:创建一个新的事务。 -
b
方法:加入a
方法的事务。
异常情况:
-
a
方法发生异常:b
方法的操作会回滚,因为它们在同一个事务中。 -
b
方法发生异常:a
方法的操作会回滚,因为它们在同一个事务中。
场景4:a
方法使用 REQUIRED
,b
方法使用 NOT_SUPPORTED
-
a
方法:创建一个新的事务。 -
b
方法:以非事务方式执行,挂起a
方法的事务。
异常情况:
-
a
方法发生异常:b
方法的操作不会回滚,因为b
方法以非事务方式执行。 -
b
方法发生异常:a
方法的操作会回滚,因为a
方法在事务中。
场景5:a
方法使用 REQUIRED
,b
方法使用 MANDATORY
-
a
方法:创建一个新的事务。 -
b
方法:加入a
方法的事务。
异常情况:
-
a
方法发生异常:b
方法的操作会回滚,因为它们在同一个事务中。 -
b
方法发生异常:a
方法的操作会回滚,因为它们在同一个事务中。
场景6:a
方法使用 REQUIRED
,b
方法使用 NEVER
-
a
方法:创建一个新的事务。 -
b
方法:抛出异常,因为a
方法存在事务。
异常情况:
-
a
方法发生异常:不会到达b
方法,因为b
方法会先抛出异常。 -
b
方法发生异常:b
方法会先抛出异常,因为a
方法存在事务。
场景7:a
方法使用 REQUIRED
,b
方法使用 NESTED
-
a
方法:创建一个新的事务。 -
b
方法:在嵌套事务中执行。
异常情况:
-
a
方法发生异常:b
方法的操作会回滚,因为它们在同一个事务中。 -
b
方法发生异常:b
方法的操作会回滚,但a
方法的操作是否回滚取决于是否捕获b
方法的异常。
其他传播特性的组合场景
场景8:a
方法使用 REQUIRES_NEW
,b
方法使用 REQUIRED
-
a
方法:创建一个新的事务。 -
b
方法:加入a
方法的事务。
异常情况:
-
a
方法发生异常:b
方法的操作会回滚,因为它们在同一个事务中。 -
b
方法发生异常:a
方法的操作会回滚,因为它们在同一个事务中。
场景9:a
方法使用 REQUIRES_NEW
,b
方法使用 REQUIRES_NEW
-
a
方法:创建一个新的事务。 -
b
方法:创建一个新的事务,挂起a
方法的事务。
异常情况:
-
a
方法发生异常:b
方法的操作不会回滚,因为它们在不同的事务中。 -
b
方法发生异常:a
方法的操作不会回滚,因为它们在不同的事务中。
场景10:a
方法使用 REQUIRES_NEW
,b
方法使用 SUPPORTS
-
a
方法:创建一个新的事务。 -
b
方法:加入a
方法的事务。
异常情况:
-
a
方法发生异常:b
方法的操作会回滚,因为它们在同一个事务中。 -
b
方法发生异常:a
方法的操作会回滚,因为它们在同一个事务中。
场景11:a
方法使用 REQUIRES_NEW
,b
方法使用 NOT_SUPPORTED
-
a
方法:创建一个新的事务。 -
b
方法:以非事务方式执行,挂起a
方法的事务。
异常情况:
-
a
方法发生异常:b
方法的操作不会回滚,因为b
方法以非事务方式执行。 -
b
方法发生异常:a
方法的操作会回滚,因为a
方法在事务中。
场景12:a
方法使用 REQUIRES_NEW
,b
方法使用 MANDATORY
-
a
方法:创建一个新的事务。 -
b
方法:加入a
方法的事务。
异常情况:
-
a
方法发生异常:b
方法的操作会回滚,因为它们在同一个事务中。 -
b
方法发生异常:a
方法的操作会回滚,因为它们在同一个事务中。
场景13:a
方法使用 REQUIRES_NEW
,b
方法使用 NEVER
-
a
方法:创建一个新的事务。 -
b
方法:抛出异常,因为a
方法存在事务。
异常情况:
-
a
方法发生异常:不会到达b
方法,因为b
方法会先抛出异常。 -
b
方法发生异常:b
方法会先抛出异常,因为a
方法存在事务。
场景14:a
方法使用 REQUIRES_NEW
,b
方法使用 NESTED
-
a
方法:创建一个新的事务。 -
b
方法:在嵌套事务中执行。
异常情况:
-
a
方法发生异常:b
方法的操作会回滚,因为它们在同一个事务中。 -
b
方法发生异常:b
方法的操作会回滚,但a
方法的操作是否回滚取决于是否捕获b
方法的异常。
其他传播特性的组合场景
场景15:a
方法使用 SUPPORTS
,b
方法使用 REQUIRED
-
a
方法:以非事务方式执行。 -
b
方法:创建一个新的事务。
异常情况:
-
a
方法发生异常:b
方法的操作不会回滚,因为b
方法在独立的事务中。 -
b
方法发生异常:a
方法的操作不会回滚,因为a
方法以非事务方式执行。
场景16:a
方法使用 SUPPORTS
,b
方法使用 REQUIRES_NEW
-
a
方法:以非事务方式执行。 -
b
方法:创建一个新的事务。
异常情况:
-
a
方法发生异常:b
方法的操作不会回滚,因为b
方法在独立的事务中。 -
b
方法发生异常:a
方法的操作不会回滚,因为a
方法以非事务方式执行。
场景17:a
方法使用 SUPPORTS
,b
方法使用 SUPPORTS
-
a
方法:以非事务方式执行。 -
b
方法:以非事务方式执行。
异常情况:
-
a
方法发生异常:b
方法的操作不会回滚,因为它们都以非事务方式执行。 -
b
方法发生异常:a
方法的操作不会回滚,因为它们都以非事务方式执行。
场景18:a
方法使用 SUPPORTS
,b
方法使用 NOT_SUPPORTED
-
a
方法:以非事务方式执行。 -
b
方法:以非事务方式执行。
异常情况:
-
a
方法发生异常:b
方法的操作不会回滚,因为它们都以非事务方式执行。 -
b
方法发生异常:a
方法的操作不会回滚,因为它们都以非事务方式执行。
场景19:a
方法使用 SUPPORTS
,b
方法使用 MANDATORY
-
a
方法:以非事务方式执行。 -
b
方法:抛出异常,因为a
方法没有事务。
异常情况:
-
a
方法发生异常:不会到达b
方法,因为b
方法会先抛出异常。 -
b
方法发生异常:b
方法会先抛出异常,因为a
方法没有事务。
场景20:a
方法使用 SUPPORTS
,b
方法使用 NEVER
-
a
方法:以非事务方式执行。 -
b
方法:以非事务方式执行。
异常情况:
-
a
方法发生异常:b
方法的操作不会回滚,因为它们都以非事务方式执行。 -
b
方法发生异常:a
方法的操作不会回滚,因为它们都以非事务方式执行。
场景21:a
方法使用 SUPPORTS
,b
方法使用 NESTED
-
a
方法:以非事务方式执行。 -
b
方法:创建一个新的事务。
异常情况:
-
a
方法发生异常:b
方法的操作不会回滚,因为b
方法在独立的事务中。 -
b
方法发生异常:a
方法的操作不会回滚,因为a
方法以非事务方式执行。
其他传播特性的组合场景
场景22:a
方法使用 NOT_SUPPORTED
,b
方法使用 REQUIRED
-
a
方法:以非事务方式执行。 -
b
方法:创建一个新的事务。
异常情况:
-
a
方法发生异常:b
方法的操作不会回滚,因为b
方法在独立的事务中。 -
b
方法发生异常:a
方法的操作不会回滚,因为a
方法以非事务方式执行。
场景23:a
方法使用 NOT_SUPPORTED
,b
方法使用 REQUIRES_NEW
-
a
方法:以非事务方式执行。 -
b
方法:创建一个新的事务。
异常情况:
-
a
方法发生异常:b
方法的操作不会回滚,因为b
方法在独立的事务中。 -
b
方法发生异常:a
方法的操作不会回滚,因为a
方法以非事务方式执行。
场景24:a
方法使用 NOT_SUPPORTED
,b
方法使用 SUPPORTS
-
a
方法:以非事务方式执行。 -
b
方法:以非事务方式执行。
异常情况:
-
a
方法发生异常:b
方法的操作不会回滚,因为它们都以非事务方式执行。 -
b
方法发生异常:a
方法的操作不会回滚,因为它们都以非事务方式执行。
场景25:a
方法使用 NOT_SUPPORTED
,b
方法使用 NOT_SUPPORTED
-
a
方法:以非事务方式执行。 -
b
方法:以非事务方式执行。
异常情况:
-
a
方法发生异常:b
方法的操作不会回滚,因为它们都以非事务方式执行。 -
b
方法发生异常:a
方法的操作不会回滚,因为它们都以非事务方式执行。
场景26:a
方法使用 NOT_SUPPORTED
,b
方法使用 MANDATORY
-
a
方法:以非事务方式执行。 -
b
方法:抛出异常,因为a
方法没有事务。
异常情况:
-
a
方法发生异常:不会到达b
方法,因为b
方法会先抛出异常。 -
b
方法发生异常:b
方法会先抛出异常,因为a
方法没有事务。
场景27:a
方法使用 NOT_SUPPORTED
,b
方法使用 NEVER
-
a
方法:以非事务方式执行。 -
b
方法:以非事务方式执行。
异常情况:
-
a
方法发生异常:b
方法的操作不会回滚,因为它们都以非事务方式执行。 -
b
方法发生异常:a
方法的操作不会回滚,因为它们都以非事务方式执行。
场景28:a
方法使用 NOT_SUPPORTED
,b
方法使用 NESTED
-
a
方法:以非事务方式执行。 -
b
方法:创建一个新的事务。
异常情况:
-
a
方法发生异常:b
方法的操作不会回滚,因为b
方法在独立的事务中。 -
b
方法发生异常:a
方法的操作不会回滚,因为a
方法以非事务方式执行。
其他传播特性的组合场景
场景29:a
方法使用 MANDATORY
,b
方法使用 REQUIRED
-
a
方法:必须在已有事务中执行,如果没有事务则抛出异常。 -
b
方法:加入a
方法的事务。
异常情况:
-
a
方法发生异常:b
方法的操作会回滚,因为它们在同一个事务中。 -
b
方法发生异常:a
方法的操作会回滚,因为它们在同一个事务中。
场景30:a
方法使用 MANDATORY
,b
方法使用 REQUIRES_NEW
-
a
方法:必须在已有事务中执行,如果没有事务则抛出异常。 -
b
方法:创建一个新的事务,挂起a
方法的事务。
异常情况:
-
a
方法发生异常:b
方法的操作不会回滚,因为它们在不同的事务中。 -
b
方法发生异常:a
方法的操作不会回滚,因为它们在不同的事务中。
场景31:a
方法使用 MANDATORY
,b
方法使用 SUPPORTS
-
a
方法:必须在已有事务中执行,如果没有事务则抛出异常。 -
b
方法:加入a
方法的事务。
异常情况:
-
a
方法发生异常:b
方法的操作会回滚,因为它们在同一个事务中。 -
b
方法发生异常:a
方法的操作会回滚,因为它们在同一个事务中。
场景32:a
方法使用 MANDATORY
,b
方法使用 NOT_SUPPORTED
-
a
方法:必须在已有事务中执行,如果没有事务则抛出异常。 -
b
方法:以非事务方式执行,挂起a
方法的事务。
异常情况:
-
a
方法发生异常:b
方法的操作不会回滚,因为b
方法以非事务方式执行。 -
b
方法发生异常:a
方法的操作会回滚,因为a
方法在事务中。
场景33:a
方法使用 MANDATORY
,b
方法使用 MANDATORY
-
a
方法:必须在已有事务中执行,如果没有事务则抛出异常。 -
b
方法:加入a
方法的事务。
异常情况:
-
a
方法发生异常:b
方法的操作会回滚,因为它们在同一个事务中。 -
b
方法发生异常:a
方法的操作会回滚,因为它们在同一个事务中。
场景34:a
方法使用 MANDATORY
,b
方法使用 NEVER
-
a
方法:必须在已有事务中执行,如果没有事务则抛出异常。 -
b
方法:抛出异常,因为a
方法存在事务。
异常情况:
-
a
方法发生异常:不会到达b
方法,因为b
方法会先抛出异常。 -
b
方法发生异常:b
方法会先抛出异常,因为a
方法存在事务。
场景35:a
方法使用 MANDATORY
,b
方法使用 NESTED
-
a
方法:必须在已有事务中执行,如果没有事务则抛出异常。 -
b
方法:在嵌套事务中执行。
异常情况:
-
a
方法发生异常:b
方法的操作会回滚,因为它们在同一个事务中。 -
b
方法发生异常:b
方法的操作会回滚,但a
方法的操作是否回滚取决于是否捕获b
方法的异常。
其他传播特性的组合场景
场景36:a
方法使用 NEVER
,b
方法使用 REQUIRED
-
a
方法:以非事务方式执行。 -
b
方法:抛出异常,因为a
方法没有事务。
异常情况:
-
a
方法发生异常:不会到达b
方法,因为b
方法会先抛出异常。 -
b
方法发生异常:b
方法会先抛出异常,因为a
方法没有事务。
场景37:a
方法使用 NEVER
,b
方法使用 REQUIRES_NEW
-
a
方法:以非事务方式执行。 -
b
方法:创建一个新的事务。
异常情况:
-
a
方法发生异常:b
方法的操作不会回滚,因为b
方法在独立的事务中。 -
b
方法发生异常:a
方法的操作不会回滚,因为a
方法以非事务方式执行。
场景38:a
方法使用 NEVER
,b
方法使用 SUPPORTS
-
a
方法:以非事务方式执行。 -
b
方法:以非事务方式执行。
异常情况:
-
a
方法发生异常:b
方法的操作不会回滚,因为它们都以非事务方式执行。 -
b
方法发生异常:a
方法的操作不会回滚,因为它们都以非事务方式执行。
场景39:a
方法使用 NEVER
,b
方法使用 NOT_SUPPORTED
-
a
方法:以非事务方式执行。 -
b
方法:以非事务方式执行。
异常情况:
-
a
方法发生异常:b
方法的操作不会回滚,因为它们都以非事务方式执行。 -
b
方法发生异常:a
方法的操作不会回滚,因为它们都以非事务方式执行。
场景40:a
方法使用 NEVER
,b
方法使用 MANDATORY
-
a
方法:以非事务方式执行。 -
b
方法:抛出异常,因为a
方法没有事务。
异常情况:
-
a
方法发生异常:不会到达b
方法,因为b
方法会先抛出异常。 -
b
方法发生异常:b
方法会先抛出异常,因为a
方法没有事务。
场景41:a
方法使用 NEVER
,b
方法使用 NEVER
-
a
方法:以非事务方式执行。 -
b
方法:以非事务方式执行。
异常情况:
-
a
方法发生异常:b
方法的操作不会回滚,因为它们都以非事务方式执行。 -
b
方法发生异常:a
方法的操作不会回滚,因为它们都以非事务方式执行。
场景42:a
方法使用 NEVER
,b
方法使用 NESTED
-
a
方法:以非事务方式执行。 -
b
方法:抛出异常,因为a
方法没有事务。
异常情况:
-
a
方法发生异常:不会到达b
方法,因为b
方法会先抛出异常。 -
b
方法发生异常:b
方法会先抛出异常,因为a
方法没有事务。
其他传播特性的组合场景
场景43:a
方法使用 NESTED
,b
方法使用 REQUIRED
-
a
方法:创建一个新的事务。 -
b
方法:加入a
方法的事务。
异常情况:
-
a
方法发生异常:b
方法的操作会回滚,因为它们在同一个事务中。 -
b
方法发生异常:a
方法的操作会回滚,因为它们在同一个事务中。
场景44:a
方法使用 NESTED
,b
方法使用 REQUIRES_NEW
-
a
方法:创建一个新的事务。 -
b
方法:创建一个新的事务,挂起a
方法的事务。
异常情况:
-
a
方法发生异常:b
方法的操作不会回滚,因为它们在不同的事务中。 -
b
方法发生异常:a
方法的操作不会回滚,因为它们在不同的事务中。
场景45:a
方法使用 NESTED
,b
方法使用 SUPPORTS
-
a
方法:创建一个新的事务。 -
b
方法:加入a
方法的事务。
异常情况:
-
a
方法发生异常:b
方法的操作会回滚,因为它们在同一个事务中。 -
b
方法发生异常:a
方法的操作会回滚,因为它们在同一个事务中。
场景46:a
方法使用 NESTED
,b
方法使用 NOT_SUPPORTED
-
a
方法:创建一个新的事务。 -
b
方法:以非事务方式执行,挂起a
方法的事务。
异常情况:
-
a
方法发生异常:b
方法的操作不会回滚,因为b
方法以非事务方式执行。 -
b
方法发生异常:a
方法的操作会回滚,因为a
方法在事务中。
场景47:a
方法使用 NESTED
,b
方法使用 MANDATORY
-
a
方法:创建一个新的事务。 -
b
方法:加入a
方法的事务。
异常情况:
-
a
方法发生异常:b
方法的操作会回滚,因为它们在同一个事务中。 -
b
方法发生异常:a
方法的操作会回滚,因为它们在同一个事务中。
场景48:a
方法使用 NESTED
,b
方法使用 NEVER
-
a
方法:创建一个新的事务。 -
b
方法:抛出异常,因为a
方法存在事务。
异常情况:
-
a
方法发生异常:不会到达b
方法,因为b
方法会先抛出异常。 -
b
方法发生异常:b
方法会先抛出异常,因为a
方法存在事务。
场景49:a
方法使用 NESTED
,b
方法使用 NESTED
-
a
方法:创建一个新的事务。 -
b
方法:在嵌套事务中执行。
异常情况:
-
a
方法发生异常:b
方法的操作会回滚,因为它们在同一个事务中。 -
b
方法发生异常:b
方法的操作会回滚,但a
方法的操作是否回滚取决于是否捕获b
方法的异常。
这些场景涵盖了所有可能的传播特性组合,并详细说明了每种组合下的事务行为以及在 a
方法或 b
方法发生异常时的事务行为。
-
在场景36中,
b
方法会抛出异常,因为它需要一个事务而a
方法没有事务。 -
在场景37中,
b
方法不会抛出异常,因为它可以创建自己的事务。