2012-11-30 44 views
3

我已經在我的實體bean,我通過JNDI查找配置工作管理器。更改背後的想法是多線程化一些驗證,因爲它可能很耗時,但這需要訪問當前事務。共享交易的WebLogic的WorkManager線程(使用CommonJ)

從我的測試看來,在工作線程中看不到事務。我非常想在我的工作線程中訪問事務 - 我可以這樣做嗎?

我希望做類似這樣的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

<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> 
在bean定義參考

然後在我的代碼中,我查找了工作管理器並安排了一些工作來執行。

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。我對這些類的初步測試似乎不起作用。也許我錯過了什麼?從Oracle支持呼叫

+0

僅供參考CommonJ不是必須的,但這是我一直在做的事情。 – mrswadge

回答

3

官方消息:

不可能/支持。 JTA有一個單線程模型。

在一個單一的 事務中可能涉及多個線程的情況是有一個調用到遠程服務器的地方。遠程服務器 已被列爲子協調器。即使如此,控制的整體流程 是單線程的,因此將此模型擴展到線程的本地池 不會爲您購買任何東西。