【问题标题】:Sharing transaction across WebLogic WorkManager threads (using CommonJ)跨 WebLogic WorkManager 线程共享事务(使用 CommonJ)
【发布时间】:2012-11-30 11:31:57
【问题描述】:

我已经在我通过 JNDI 查找的实体 bean 上配置了工作管理器。更改背后的想法是对一些验证进行多线程处理,因为这可能很耗时,但这需要访问当前事务。

根据我的测试,似乎无法在工作线程中访问事务。我非常想在我的工作线程中访问事务 - 我可以这样做吗?

我希望做类似于ExecutionContext 的事情,其中​​ XID 对象在安排工作时传递,这意味着它继承了当前事务。 WebLogic 支持吗?

这就是我所做的:

我已向weblogic-ejb-jar.xml 添加了一个工作管理器定义,如下所示:

  <work-manager>
    <name>wm/EJBWorkManager</name>
    <min-threads-constraint>
      <name>EJBWorkManager_MinThreadCount</name>
      <count>5</count>
    </min-threads-constraint>
  </work-manager>

在ejb-jar.xml中添加了对bean定义的引用

  <resource-ref>
    <description>Work Manager allows multi-threading of defined units of work.</description>
    <res-ref-name>wm/EJBWorkManager</res-ref-name>
    <res-type>commonj.work.WorkManager</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>

然后在我的代码中,我查找了工作管理器并安排了一些工作来执行。

weblogic.transaction.Transaction tx = ( weblogic.transaction.Transaction ) weblogic.transaction.TransactionHelper.getTransactionHelper().getTransaction();
log.info( tx != null ? tx.getXid().toString() : "No Transaction" );
try {
  InitialContext initialContext = new InitialContext();
  WorkManager workManager = ( WorkManager ) initialContext.lookup( "java:comp/env/wm/EJBWorkManager" );
  List<WorkItem> workItems = new ArrayList<WorkItem>(); 
  for ( int i = 0; i < 2; i++ ) {
    Work work = new Work() {
      public void run() {
        weblogic.transaction.Transaction tx = ( weblogic.transaction.Transaction ) weblogic.transaction.TransactionHelper.getTransactionHelper().getTransaction();
        log.info( tx != null ? tx.getXid().toString() : "No Transaction" );
      }
      public boolean isDaemon() {
        return false;
      }
      public void release() {
      }
    };
    workItems.add( workManager.schedule( work ) );
  }
  workManager.waitForAll( workItems, WorkManager.INDEFINITE );
} catch ( NamingException e ) {
  throw new RemoteException( "Error", e );
} catch ( IllegalArgumentException e ) {
  throw new RemoteException( "Error", e );
} catch ( InterruptedException e ) {
  throw new RemoteException( "Error", e );
} catch ( WorkException e ) {
  throw new RemoteException( "Error", e );
}

我得到的输出如下,表明事务在衍生线程中不可用。是否可以将此事务共享到工作线程中?我认为他们已将其作为 JCA 1.5 (JSR 112) 的一部分。

16 [[ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'] INFO com.tracegroup.isys.weblogic.beans.session.SimpleEJB - BEA1-0474BACB4707C088B359
16 [[STANDBY] ExecuteThread: '10' for queue: 'weblogic.kernel.Default (self-tuning)'] INFO com.tracegroup.isys.weblogic.beans.session.SimpleEJB - No Transaction
16 [[STANDBY] ExecuteThread: '10' for queue: 'weblogic.kernel.Default (self-tuning)'] INFO com.tracegroup.isys.weblogic.beans.session.SimpleEJB - No Transaction

编辑:我也尝试过使用 weblogic.connector.work.WorkManager 和 javax.resource.spi.work.WorkManager,但是在执行 JNDI 查找时这些都没有返回。这些似乎确实允许将 ExecutionContext 传递给工作管理器,从而允许给出 XID。我对这些类的初始测试似乎不起作用。也许我错过了什么?

【问题讨论】:

  • 仅供参考:CommonJ 不是必须的,但这是我目前一直在使用的。

标签: jakarta-ee transactions weblogic weblogic-10.x workmanagers


【解决方案1】:

来自 Oracle 支持电话的官方消息:

不可能/不支持。 JTA 有一个单线程模型。

单个线程可以涉及多个线程的一种情况 事务是调用远程服务器的地方。遥控器 服务器被登记为子协调器。即便如此,整体流量 控制是单线程的,因此将此模型扩展到本地池 线程不会给你买任何东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-12
    • 1970-01-01
    • 2013-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多