【问题标题】:Will a TransactionAttributeType.REQUIRES_NEW annotated method run on a new Thread?TransactionAttributeType.REQUIRES_NEW 注释方法会在新线程上运行吗?
【发布时间】:2017-07-30 07:23:56
【问题描述】:

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

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

【问题讨论】:

    标签: java multithreading transactions jta


    【解决方案1】:

    Java-Doc中所述:

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

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

    【讨论】:

    • 所以这意味着旧事务被阻止/等待新事务完成,对吧?
    • 没错,新事务完成后会继续。
    • 只提一个常见的误解:有可能或极有可能,暂停的事务(如果有的话)不会“看到”“REQUIRES_NEW”所做的任何更改-事务,方法返回后。
    【解决方案2】:

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

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

    当使用事务上下文调用具有事务属性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 和事务属性以声明方式实现这一点。另请注意,此属性可能会导致过度使用过多的事务开销。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-09
      相关资源
      最近更新 更多