【问题标题】:MDB with container managed transaction & worker thread具有容器管理事务和工作线程的 MDB
【发布时间】:2012-11-15 17:05:43
【问题描述】:

我有一个使用容器管理事务的 MDB(我的容器是 IBM Websphere 7)。

Websphere 正在使用全局 (JTA) 事务。

如果我的 MDB 线程启动了一个工作线程,并且该线程开始了一个事务,那么该新线程是否会与 MDB 在同一个事务中?

我希望 MDB 线程在我的工作线程成功启动后立即提交其事务并确认 MQ 消息。如果工作线程回滚,我不希望我的 MDB 回滚。

编辑:线程中的代码有这个 - 它没有使用注释:

    txn = (UserTransaction)ctx.lookup("java:comp/UserTransaction");
    txn.begin();

因此,如果查看 txn.getStatus(),它将不是 STATUS_NO_TRANSACTION。因此,我需要获取适用于 Websphere 7 的事务管理器并在 txn.begin() 之前调用“suspend()”?预防问题的正确方法是什么?

【问题讨论】:

    标签: multithreading jakarta-ee websphere jta message-driven-bean


    【解决方案1】:

    将不应该与onMessage()方法在同一个事务中的代码放到一个单独的方法中,并将该方法的事务属性设置为REQUIRES_NEW。这将在调用该方法时创建一个新事务,并且此新事务的成功或失败不会影响先前存在的事务。

    顺便说一句,您不应该在 JavaEE 应用程序中进行显式线程管理。

    来自 EJB 3.0 规范:

    企业 bean 不得尝试管理线程。企业 bean 不得尝试启动、停止、挂起或恢复线程,或 更改线程的优先级或名称。企业 bean 不得 尝试管理线程组。

    您可以考虑使用计时器服务来有效地创建单独的线程,同时将线程管理留给服务器。

    【讨论】:

    • 我们正在使用这样的东西来启动线程:com.ibm.asynchbeans.WorkManager.startWork(...)
    • 好的,太好了。只需更改事务属性,然后就可以了。
    • 我发布了对我原来的问题的编辑,该问题是关于正确的实施方式需要此代码中的新内容。谢谢。
    • 所有您需要做的就是为包含线程相关代码的部署描述符中的方法设置事务属性。您不需要按照您描述的方式在 EJB 中执行任何与事务相关的显式编码。
    【解决方案2】:

    如果您使用的是 ejb 3.1,则可以选择在带有注释的方法中进行工作人员工作

    @Asynchronous
    

    这将为您提供一个新事务,并且该工作将在单独的线程中执行。

    http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/asyncMethodOfEJB/AsyncMethodEJB.html

    阅读更多关于默认交易模式:Default EJB transaction mode for asynchronous methods?

    【讨论】:

      猜你喜欢
      • 2016-02-26
      • 2013-05-26
      • 2017-06-23
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      • 2013-03-27
      • 1970-01-01
      • 2020-06-12
      相关资源
      最近更新 更多