2012-03-20 50 views
1

當前我開發了一個JCA出站適配器(支持LocalTransaction),並且在連接管理方面遇到了一些麻煩。我的適配器工作正常,除了服務器(WebLogic 12c)沒有將ManagedConnections放回到池中。根據JavaDoc,服務器必須調用ManagedConnection.cleanup()重新初始化連接並將其放回池中,但事實並非如此。JCA ManagedConnection生命週期

當我使用EJB中的適配器時,服務器創建一個新的ManagedConnection,開始一個新的事務,提交它,但不調用ManagedConnection.cleanup()方法並且不會將它放回池中。

下面你可以看到我的測試豆:

@Stateless(mappedName = "TestingBean") 
@Local(value = TestingBeanLocal.class) 
@Remote(value = TestingBeanRemote.class) 
@TransactionManagement(value = TransactionManagementType.CONTAINER) 
@TransactionAttribute(value = TransactionAttributeType.REQUIRES_NEW) 
public class TestingBean implements TestingBeanCommon{ 

@Resource(mappedName = "eis/myJCA") 
private MyDataSource dataSource; 

@Override 
public void performTestAction(String param1, String param2) { 
    MyConnection connection = dataSource.getMyConnection(); 
    connection.performAction(ActionFactory.getSomeAction(param1, param2)); 
} 
} 

10後調用我得到如下:

取得初步背景 javax.ejb.EJBException異常:EJB異常:;嵌套的異常是: java.lang.RuntimeException:javax.resource.spi.ApplicationServerInternalException:無法獲取pool =「eis/myJCA」的連接,weblogic.common.resourcepool.ResourceLimitException:配置的最大數量限制爲(0)允許等待資源達到池eis/myJCA的線程數

正如您注意到的,它對每次調用都使用新的事務(REQUIRES_NEW屬性)。服務器首先創建一個新的ManagedConnection實例10次,然後連接池達到其最大容量。

從跟蹤日誌可以明顯看出,沒有發生任何單個呼叫ManagedConnection.cleanup(),並且池中的每個連接都處於忙碌狀態。我讀過的JCA規範,發現該適配器可發送生命週期事件使用回調函數的聽衆,但任何企圖利用這些事件偵聽器回調了新的異常結束:

javax.ejb.EJBException異常:BEA1 -001471C1E76DE5A4E067;嵌套的異常是: weblogic.transaction.nonxa.NonXAException:java.lang.IllegalStateException:[Connector:199175]此ManagedConnection由容器管理其事務行爲並已通過容器入伍到JTA事務;應用程序/適配器不得調用本地事務開始/提交/回滾API。從適配器拒絕事件LOCAL_TRANSACTION_COMMITTED。 javax.ejb.EJBException:EJB異常:;嵌套的異常是: java.lang.IllegalStateException:[Connector:199175]此ManagedConnection由容器管理其事務行爲,並已通過容器入伍到JTA事務;應用程序/適配器不得調用本地事務開始/提交/回滾API。拒絕來自適配器的事件LOCAL_TRANSACTION_ROLLEDBACK。

我想WebLogic不會等待任何事件(也許我發錯了?)。

那麼,我做錯了什麼?如何讓服務器把連接放回池中?

UPD:我發現連接事件對服務器非常重要。服務器根據事件信息來管理連接,這些事件信息發送給監聽器,並將其註冊到ManagedConnection。現在我在適配器中支持事件,但WebLogic仍然不想將連接放回池中。目前,我獲得以下事件日誌:

  1. LOCAL_TRANSACTION_STARTED
  2. 連接關閉
  3. LOCAL_TRANSACTION_COMMITTED

它看起來很好,我(在連接關閉事件意味着應用程序關閉了連接,我加了close方法,即發送此事件)。提交成功並且不會出現例外情況。看起來我已經按照正確的順序發送了事件(早期的WebLogic引發異常,但現在停止這樣做),但服務器仍然不會將連接返回到池。

我很困惑。

+0

如果你只是在連接上調用'close()'(如果實現的話)會怎麼樣?基於連接的JCA API通常需要這個。關閉主題,但您可以省略@ TransactionManagement,最有可能的是mappedname。第一個是默認設置,第二個很少需要。 – 2012-03-20 08:17:20

+0

我沒有實現'close()'方法。這種方法應該做什麼?我在JCA文件適配器示例中看到了close方法,其中此方法只是將'CONNECTION_CLOSED'事件發送給偵聽器,但WebLogic不會等待事件...順便說一句,我完全同意您關於'mappedName'和'@TransactionManagement '屬性。 – gkuzmin 2012-03-20 08:24:31

回答

1

看來我已經解決了這個問題。當我查看WebLogic控制檯時,我發現ManagedConnection實例有-1個活動處理程序。所以我決定評論MyConnection.close()方法調用,我添加到我的測試bean發送CONNECTION_CLOSED事件。在這個chages之後,連接池開始工作很好。我試圖修改我的測試bean並將其事務屬性設置爲NOT_SUPPORTED。之後,ManagedConnections池中有1個活動處理程序。所以我把MyConnection.close()線和連接池再次開始工作。

我假設發送CONNECTION_CLOSED事件在事務傳播的情況下是錯誤的。此外,我還假設發送CONNECTION_CLOSED事件的方法ManagedConnection.close()應該用於單事務的情況。但對我來說,似乎很奇怪,WebLogic不想清理ManagedConnections,並且如果它們具有負數的活動處理程序,則將其放回原處。

非常感謝您的幫助。

+0

+1爲您的努力!這些問題可能會變得模糊。 – ewernli 2012-04-19 13:54:51