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

时间:2017-07-30 07:23:57

标签: java multithreading transactions jta

根据documentation,在容器管理的事务中,如果方法使用TransactionAttributeType.REQUIRES_NEW属性进行注释,将暂停任何客户端事务,委托对此方法的调用/创建新事务,并继续执行新任务完成后的先前交易。

所以这实际上意味着,没有创建新的线程,并且上一个事务处于“等待”状态,直到新的线程完成为止?

2 个答案:

答案 0 :(得分:1)

Java-Doc中所述:

  

如果客户端使用事务上下文调用,则容器会在启动新事务并调用该方法之前挂起事务上下文与当前线程的关联。在方法和新事务完成后,容器将恢复挂起的事务关联。

它不会放弃线程或创建新线程,它只释放与事务的关联并在之后重新创建它。如果它会创建一个新线程,则不需要删除该关联,因为它从未被删除。

答案 1 :(得分:1)

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

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

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

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

作为附注,正如您可能知道的那样,Bean Managed Transaction无法暂停事务,您无法以编程方式执行此操作。只有JTA可以使用它的内部事务管理API来执行此操作,您可以使用CMT和事务属性以声明方式实现此目的。另请注意,此属性可能导致过度使用过多的事务开销。