TransactionAttributeType.REQUIRES_NEW
,它将暂停任何客户端事务,将调用委托给此方法/创建一个新的事务,并在新的事务完成后恢复之前的事务。因此,这实际上意味着没有创建新线程,并且之前的事务处于“等待”状态,直到新的事务完成为止?
TransactionAttributeType.REQUIRES_NEW
,它将暂停任何客户端事务,将调用委托给此方法/创建一个新的事务,并在新的事务完成后恢复之前的事务。容器管理的事务
指的是JTA
,而JTA
规范不允许跨越多个线程的事务。每个JTA事务都与执行线程相关联,这意味着在任何给定时间最多只能有一个事务处于活动状态。请注意,可以将多个事务与单个线程关联,但是再次强调,在任何给定时间只能有一个事务处于活动状态。
由于JTA
不支持嵌套事务,因此如果一个事务处于活动状态,则不可能在同一线程中启动另一个事务,直到第一个事务提交或回滚(或超时并再次回滚),从而释放当前线程的事务关联。
当使用事务属性REQUIRES_NEW
的方法在事务上下文中被调用时,背后发生了什么?首先,JTA通过调用其内部API(特别是调用TransactionManager.suspend()
)暂时挂起当前与调用线程相关联的事务。(如果调用线程未关联任何事务(即使用事务属性NOT_SUPPORTED
或没有事务上下文调用方法),则返回null对象引用),并获取Transaction
对象。一旦上述REQUIRES_NEW
方法完成,将通过TransactionManager.resume()
方法将此Transaction
对象传递给它以重新将事务上下文与调用线程关联。无论是在同一线程还是在另一个线程上取决于JTA实现,因为规范并没有明确要求它是这样还是那样。
回答您的问题-当在事务上下文中调用具有事务属性REQUIRES_NEW
的方法时,JTA实现事务唯一的方式是挂起线程中的事务并稍后在同一线程或另一个线程上恢复它。何时恢复?请记住,REQUIRES_NEW
属性基本上意味着注释方法始终必须处于自己的事务中,这反过来又意味着该方法应该独立于调用堆栈上方的方法进行提交或回滚。挂起的事务将在带有事务属性REQUIRES_NEW
的被调用方法提交或回滚后恢复。
作为附注,您可能已经知道,Bean Managed Transaction
无法暂停事务,您无法通过编程方式执行此操作。只有JTA可以使用其内部事务管理API执行此操作,并且您可以通过使用CMT
和事务属性以声明方式实现此操作。还要注意,如果过度使用此属性,可能会导致过多的事务开销。