TransactionAttributeType.REQUIRES_NEW 注释方法 运行 会在新线程上吗?

Will a TransactionAttributeType.REQUIRES_NEW annotated method run on a new Thread?

根据documentation,在容器管理的事务中,如果一个方法被注释为TransactionAttributeType.REQUIRES_NEW属性,将暂停任何客户端事务,委托调用这个方法/创建一个新事务,并且新交易完成后恢复到以前的交易。

所以这实际上意味着,没有创建新线程,之前的事务处于 "wait" 状态,直到新线程完成?

Java-Doc 中所述:

If a client calls with a transaction context, the container suspends the association of the transaction context with the current thread before starting the new transaction and invoking the method. The container resumes the suspended transaction association after the method and the new transaction have been completed.

不是放弃线程也不是创建新线程,只是释放与事务的关联,然后重新创建。如果它会创建一个新线程,则不需要删除关联,因为它从未创建过。

Container managed transactions 表示 JTA 并且 JTA 规范不允许事务跨越多个线程。每个 JTA 事务都与一个执行线程相关联,因此这意味着 在任何给定时间最多可以有一个事务处于活动状态 。请注意,多个事务可以与单个线程相关联,但在给定时间只能有一个处于活动状态。

由于JTA不支持嵌套事务,这意味着如果一个事务处于活动状态,则不可能在同一线程中启动另一个事务,直到第一个事务提交或回滚(或定时out,再次导致回滚),从而释放与当前线程的事务关联。

当使用事务上下文调用具有事务属性 REQUIRES_NEW 的方法时,幕后会发生什么?首先,JTA 通过调用内部 API,特别是调用 TransactionManager.suspend() 暂时挂起当前与调用线程关联的事务。 (如果调用线程未与任何事务相关联(即使用 NOT_SUPPORTED 的事务属性或没有事务上下文调用方法),则返回空对象引用)并获取 Transaction 对象。一旦上述 REQUIRES_NEW 方法完成,此 Transaction 对象将被传递给 TransactionManager.resume() 方法以重新关联事务上下文与调用线程。是在同一个线程上还是在另一个线程上取决于 JTA 实现,因为规范确实明确要求它是一种方式或另一种方式。

回答您的问题 - 在事务上下文中调用时 JTA 实现事务属性 REQUIRES_NEW 的唯一方法是从一个线程暂停事务,稍后在同一线程或另一个线程上恢复它。什么时候恢复?请记住,REQUIRES_NEW 属性基本上意味着带注释的方法总是 必须在其 OWN TRANSACTION 中, 反过来意味着 方法应该被提交或滚动独立于方法进一步调用堆栈。一旦调用具有事务属性REQUIRES_NEW的方法提交或回滚,挂起的事务将恢复。

附带说明一下,您可能知道,Bean Managed Transaction 无法暂停交易,您无法通过编程方式进行。只有 JTA 可以使用它的内部事务管理 API 来做到这一点,您可以通过使用 CMT 和事务属性以声明方式实现这一点。另请注意,此属性可能导致过多的事务开销被过度使用。