【问题标题】:Using Transaction with runnable使用可运行的事务
【发布时间】:2018-10-05 13:53:51
【问题描述】:

我有一个使用这种方法的@Singleton ejb 类。事务在方法主体的末尾提交,但我在 myRunnable 线程中有一些其他的东西,我希望它包含在当前事务中。有什么办法吗?

@PostConstruct
public void init() {
    try {
        // do some other stuff
        managedExecutorService.execute(myRunnable);
    } catch (Exception e) {
        LOG.error("Error when initializing...", e);
    }
}

【问题讨论】:

  • 赞成以补偿奇怪的反对票。

标签: jakarta-ee transactions ejb


【解决方案1】:

您的“myRunnable 线程”不能包含在您正在运行的事务中。

您不得使用 java 执行器服务 (EJB Spec 16.2.2) 或直接管理线程:

企业 bean 不得尝试管理线程。 ...这些功能是为 EJB 容器保留的。允许企业 bean 管理线程会降低容器正确管理运行时环境的能力。

您必须使用 Java EE 7 引入的managed executor service

关于交易,文档说:

任务在 Java™ EE Product Provider 提供的托管线程中运行,并在提交任务的应用程序组件上下文中运行。所有任务都在没有显式事务的情况下运行(它们不参与应用程序组件的事务)。如果需要事务,请使用 UserTransaction 实例。在 JNDI 中使用名称“java:comp/UserTransaction”或通过使用 Resource 注释请求注入 UserTransaction 对象可以使用 UserTransaction 实例。

【讨论】:

    【解决方案2】:

    不,无法在 2 个线程之间共享事务上下文。

    出于同样的原因,您不能将事务上下文传输到异步 EJB 调用。

    您应该将事务视为始终受线程限制的事物。

    【讨论】:

      【解决方案3】:

      您可以使用 TransactionAttributeType.MANDATORY 创建 1 个调用其他 2 个方法的方法

      public void yourMethod(){
          yourMethod1();
          yourMethod2();
      }
      
      @TransactionAttribute(TransactionAttributeType.MANDATORY)
      private void yourMethod1(){
      }
      
      @TransactionAttribute(TransactionAttributeType.MANDATORY)
      private void yourMethod2(){
      }
      

      TransactionAttributeType.MANDATORY 将使用来自调用者的事务

      【讨论】:

      • 哪两种方法?我说的不是 2 个方法,而是 2 个线程。
      • EJB 中的注解 TransactionAttribute 仅用于业务方法。您的示例方法是私有的,因此根本没有业务方法。即使是公共访问,从类中直接调用此方法也不会导致对 EJB 的业务调用。我只是在调用方法的托管上下文中运行的 java 类中的一个方法委托。
      猜你喜欢
      • 2018-05-03
      • 2014-05-07
      • 1970-01-01
      • 2019-07-05
      • 1970-01-01
      • 2021-12-08
      • 1970-01-01
      • 1970-01-01
      • 2021-09-28
      相关资源
      最近更新 更多