事务传播的真实场景

Real life scenarios for Transaction propagations

有各种事务传播喜欢

REQUIRED - DML操作就是这样。

SUPPORTS - 这是查询数据库的情况。

MANDATORY - ?
REQUIRES_NEW - ?
NOT_SUPPORTED - ?
NEVER - ?
NESTED - ?

这些交易传播有哪些现实生活场景?为什么这些非常适合那种情况?

用法多种多样,没有简单的答案,但我会尽量解释清楚

  • MANDATORY(期望事务):通常在您期望任何 "higher-context" 层启动事务并且您只想继续其中时使用。例如,如果您希望一个事务用于从 HTTP 请求到响应的整个操作。然后您在 JAX-RS 资源级别开始事务,较低层(服务)需要事务到 运行 内(否则抛出异常)。
  • REQUIRES_NEW(始终创建新事务):这将创建一个新事务并暂停当前事务(如果存在)。例如,在上面的示例中,这是您在 JAX-RS 资源上设置的级别。或者通常情况下,如果您的流程以某种方式发生变化并且您希望将您的逻辑拆分为多个事务(因此您的代码具有多个应该分开的逻辑操作)。
  • REQUIRED(继续事务或根据需要创建):MANDATORY 和 REQUIRES_NEW 之间的某种混合。在 MANDATORY 中,您希望事务存在,对于此级别,您希望它存在,如果不存在,则创建它。通常用于类似 DAO 的服务(根据我的经验),但这实际上取决于您应用程序的逻辑。
  • SUPPORTS(调用者决定是否在事务中not/run):如果想使用与调用者相同的上下文(更高的上下文),如果你的调用者是运行宁在事务中,那么你 运行 也在。如果没有,那么您也是非事务性的。如果您希望更高的上下文来决定,也可以用于类似 DAO 的服务。
  • NESTED(子事务):我必须承认我没有在真实代码中使用这个,但通常你会创建一个真正的子事务作为某种检查站。所以它 运行s 在 "parent" 事务的上下文中,但如果失败它 returns 到那个检查点(嵌套事务的开始)。当您在应用程序中需要这种逻辑时,这可能很有用,例如,如果您想将大量项目插入数据库,提交有效项目并跟踪无效项目(这样您可以在嵌套事务失败时捕获异常但是仍然可以为有效交易提交整个交易)
  • NEVER(期望没有交易):当您想确定根本不存在交易时就是这种情况。如果事务中运行s 的某些代码到达此代码,则抛出异常。因此,这通常适用于与 MANDARTORY 完全相反的情况。例如。当您知道此代码不应影响任何交易时 - 很可能是因为交易不应该存在。
  • NOT_SUPPORTED(非事务性继续):这比 NEVER 更弱,您希望代码 运行 非事务性。如果您以某种方式从事务所在的上下文中输入此代码,您将暂停此事务并继续进行非事务处理。

根据我的经验,您通常希望一个业务操作是原子的。因此,每个请求您只需要一个事务/...例如,通过 HTTP 的简单 REST 调用在一个类似 HTTP 的事务中执行一些数据库操作。所以我的典型用法是 REQUIRES_NEW 在顶层(JAX-RS 资源)和 MANDATORY 在所有注入的低层服务上到此资源(或更低)。

这可能对您有用。它描述了代码在给定传播(调用者->方法)下的行为方式

  • 需要:NONE->T1,T1->T1
  • REQUIRES_NEW: NONE->T1, T1->T2
  • 强制性:NONE->异常,T1->T1
  • NOT_SUPPORTED: NONE->NONE, T1->NONE
  • 支持: NONE->NONE, T1->T1
  • 从不:NONE->NONE,T1->异常