跳到主要内容

事务传播行为

当多个事务方法在同一线程中相互调用时,传播行为决定了事务如何在这些方法间传播。

加入已有事务 (REQUIRED)

尝试加入已经存在的事务中,如果没有则开启一个新的事务。

  • 常量 Propagation.REQUIRED
时序事务 A事务 B效果
T1begin开启事务 A
T2insert data1
T3begin加入事务 A(不做操作)
T4insert data2
T5commit/rollback不做操作(由外层决定)
T6insert data3
T7commit/rollback提交/回滚事务 A

独立事务 (REQUIRES_NEW)

挂起当前已存在的事务(如果有),开启一个全新的独立事务,新事务与旧事务彼此无关。

  • 常量 Propagation.REQUIRES_NEW
信息
  • 挂起会导致当前线程绑定的 Connection 暂时不可用。
  • 挂起后事务管理器会创建一个新的 Connection 用作当前线程的数据库连接。
时序事务 A事务 B效果
T1begin开启事务 A
T2insert data1
T3begin挂起 A → 新建 Connection B → 开启事务 B
T4insert data2
T5commit/rollback提交/回滚 B → 恢复 A
T6insert data3
T7commit/rollback提交/回滚事务 A

嵌套事务 (NESTED)

在当前事务中通过 Savepoint 方式开启一个子事务。子事务回滚不影响外层事务,但外层事务回滚会连带子事务。

  • 常量 Propagation.NESTED
时序事务 A事务 B效果
T1begin开启事务 A
T2insert data1
T3begin创建 Savepoint B
T4insert data2
T5commit/rollback释放/回滚 Savepoint B
T6insert data3
T7commit/rollback提交/回滚事务 A

跟随环境 (SUPPORTS)

如果当前没有事务,以非事务方式执行;如果有事务,则加入当前事务(效果等同 REQUIRED)。

  • 常量 Propagation.SUPPORTS
信息

SUPPORTS 的本质是不作为 — 不会主动开启也不会阻止事务。

非事务方式 (NOT_SUPPORTED)

如果当前没有事务,以非事务方式执行;如果有事务,则将当前事务挂起后以非事务方式执行。

  • 常量 Propagation.NOT_SUPPORTED
时序事务 A事务 B效果
T1begin开启事务 A
T2insert data1
T3begin挂起事务 A
T4insert data2非事务方式执行
T5commit/rollback恢复事务 A
T6insert data3
T7commit/rollback提交/回滚事务 A

排除事务 (NEVER)

如果当前没有事务,以非事务方式执行;如果有事务,直接抛出异常

  • 常量 Propagation.NEVER

要求事务 (MANDATORY)

如果当前有事务,加入当前事务;如果没有事务,直接抛出异常

  • 常量 Propagation.MANDATORY

传播行为对比

传播行为无事务时有事务时
REQUIRED新建事务加入已有事务
REQUIRES_NEW新建事务挂起已有 → 新建事务
NESTED新建事务Savepoint 子事务
SUPPORTS非事务执行加入已有事务
NOT_SUPPORTED非事务执行挂起已有 → 非事务执行
NEVER非事务执行抛出异常
MANDATORY抛出异常加入已有事务