Weblogic 10.3 を使用して、JNDI データソースから取得した JDBC 接続を UserTransaction に参加させるにはどうすればよいですか?
-
20-09-2019 - |
質問
現在、JNDI を使用して Weblogic 10.3 サーバーから UserTransaction と DataSource の両方を取得しています。
データソースを「グローバル トランザクションをサポート」し、「最後のリソースのロギング」を使用するように設定しました。
私の希望は、UserTranscation を開始し、データソースから JDBC 接続を取得することで、その接続がトランザクションに参加することでした。
これは事実ではないようです。挿入ステートメントはすぐにコミットされ、トランザクションをロールバックしても効果はありません。
私の上記の仮定は正しいでしょうか?
誰かがこれを達成する方法に関するドキュメントやサンプルの方向性を教えてくれませんか?
よろしくお願いします
アップデート:
リクエストに応じて、私が使用しているコードのスケルトン概要をここに示します。
private void doSomething() {
Connection conn = null;
try {
Hashtable env = new java.util.Hashtable();
env.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
env.put(javax.naming.Context.PROVIDER_URL,"t3://localhost:8080");
InitialContext ctx = InitialContext(env));
UserTransaction transaction = null;
transaction = (UserTransaction) ctx.lookup("java:comp/UserTransaction");
DataSource dataSource = (DataSource) context.lookup("jdbc/xxxxx/DataSource");
conn = dataSource.getConnection();
transaction.begin();
// JDBC code goes here
transaction.commit();
} catch(Exception e) {
// TODO
if (transaction != null) {
try {
transaction.rollback();
} catch (Exception ex) {
// TODO
}
} finally {
if (con != null) {
conn.close
}
}
}
更新 2:
この問題を解決するには、次の 2 つのことを行う必要がありました。
コードの順序を変更して、最初にユーザー トランザクションを開始し、次にデータストアから接続を取得します (Pascal Thivent が指摘したとおり)。
「jdbc/xxxxx/DataSource」によって参照されるデータソースを XADatasource に変更します。これは、すでに LLR をサポートするように構成されている別のデータソースを使用するユーザー トランザクション内でコードを呼び出していたためであり、以下の Pascal Thivent が指摘したように、トランザクションに参加できる LLR データソースは 1 つだけであるためです。
これらの問題の両方を説明しているため、以下のPascal Thiventの回答を受け入れました。
解決
はい、あなたの仮定は正しいです、そして、によると LLR 対応の JDBC データ ソースを作成する, 、データ ソースが適切に構成されているようです。
ユーザートランザクションを開始した後、接続を取得できますか?コードまたは疑似コードを見せていただけますか?
アップデート: で述べたように LLR データ ソースのプログラミング上の考慮事項と制限事項:
- LLR データ ソースを使用してプログラミングする場合は、LLR データ ソースで getConnection を呼び出す前にグローバル トランザクションを開始する必要があります。グローバル トランザクションを開始する前に getConnection を呼び出すと、接続に対するすべての操作がグローバル トランザクションの外部で行われます。
それで、これを試してみてもらえますか?
transaction.begin(); //start the global tx before calling getConnection()
conn = dataSource.getConnection();
...
transaction.commit();
更新2: 2 番目の接続がどこから来ているかがわかりません (疑似コードにはこれが表示されていません)。ただし、同によれば、 LLR データ ソースのプログラミング上の考慮事項と制限事項:
- 単一の LLR データ ソースのインスタンスのみが特定のトランザクションに参加できます。単一の LLR データ ソースが複数の WebLogic サーバー上にインスタンスを持つ場合があり、2 つのデータ ソースは、構成された名前が同じであれば同じとみなされます。複数の LLR データ ソース インスタンスが検出され、それらが同じデータ ソースのインスタンスではない場合、トランザクション マネージャーはトランザクションをロールバックします。
実際、完全に代表的な例がないと、暗闇の中を歩いているような気分になります:)