2

現在、JCAアウトバウンドアダプター(LocalTransactionをサポート)を開発しましたが、接続管理に問題があります。サーバー(WebLogic 12c)がManagedConnectionsをプールに戻さないことを除いて、私のアダプターはうまく機能します。JavaDocによると、サーバーManagedConnection.cleanup()は接続を再初期化してプールに戻すために呼び出す必要がありますが、そうではありません。

EJBからアダプタを使用すると、サーバーは新しいManagedConnectionを作成し、新しいトランザクションを開始してコミットしますが、ManagedConnection.cleanup()メソッドを呼び出さず、プールに戻しません。

以下に私のテストBeanを示します。

@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トランザクションに登録されています。アプリケーション/アダプタは、ローカルトランザクションのbegin / commit /rollbackAPIを呼び出さないでください。アダプターからのイベントLOCAL_TRANSACTION_COMMITTEDを拒否します。javax.ejb.EJBException:EJB例外:; ネストされた例外は次のとおりです。java.lang.IllegalStateException:[Connector:199175]このManagedConnectionは、トランザクション動作のためにコンテナーによって管理され、コンテナーによってJTAトランザクションに参加しています。アプリケーション/アダプタは、ローカルトランザクションのbegin / commit /rollbackAPIを呼び出さないでください。アダプターからのイベントLOCAL_TRANSACTION_ROLLEDBACKを拒否します。

WebLogicはイベントを待機しないと思います(間違ったイベントを送信した可能性がありますか?)。

だから、私は何が間違っているのですか?サーバーに接続をプールに戻すにはどうすればよいですか?

UPD:接続イベントがサーバーにとって非常に重要であることを発見しました。サーバーは、リスナーに送信されたイベント情報に基づいて接続を管理し、リスナーはManagedConnectionに登録します。これで、アダプタでイベントをサポートしましたが、WebLogicは接続をプールに戻したくありません。現在、ログに次のイベントが表示されます。

  1. LOCAL_TRANSACTION_STARTED
  2. CONNECTION_CLOSED
  3. LOCAL_TRANSACTION_COMMITTED

私には問題ないように見えます(CONNECTION_CLOSEDイベントは、アプリケーションが接続を閉じたことを意味します。このイベントを送信するcloseメソッドを追加しました)。コミットが成功し、例外は表示されません。イベントを正しい順序で送信したようです(以前のWebLogicは例外をスローしましたが、現在はそれを停止しています)が、サーバーはまだ接続をプールに戻しません。

私は混乱しています。

4

1 に答える 1

2

この問題を解決したようです。WebLogic コンソールを調べたところ、ManagedConnection インスタンスに -1 アクティブなハンドラがあることがわかりました。そのため、イベントMyConnection.close()を送信するためにテスト Bean に追加したメソッド呼び出しにコメントを付けることにしました。CONNECTION_CLOSEDこの変更が行われた後、接続プーリングがうまく機能し始めました。テスト Bean を変更して、そのトランザクション属性を に設定しようとしましたNOT_SUPPORTED。その後ManagedConnections、プールには1つのアクティブなハンドラーがありました。そのため、回線を元に戻すMyConnection.close()と、接続プールが再び機能し始めます。

CONNECTION_CLOSEDトランザクションの伝播の場合、イベントの送信は間違っていると思います。ManagedConnection.close()また、イベントを送信するメソッドはCONNECTION_CLOSED、単一のトランザクションの場合に使用する必要があると想定しています。ManagedConnectionsしかし、アクティブなハンドラーの数が負の場合、WebLogic がそれらをクリーンアップしてプルに戻すことを望まないのは奇妙に思えます。

助けてくれてどうもありがとう。

于 2012-03-20T16:01:32.700 に答える