1

アプリケーション用に、2つのoracleインスタンス(2つの物理マシン)と1つのスキーマがあります。weblogicアプリケーションサーバーを使用しています。アプリケーションは、XAトランザクションが有効になっているデータソースを使用します。

私は1つのBeanマネージドEJBを持っていますが、ここで-

  1. テーブル内のいくつかのデータを更新してからコミットします
  2. Oracleジョブを送信する
  3. テーブル内のデータを再度更新してからコミットします

ここでエラーが発生します-java.sql.SQLException:グローバルトランザクションでローカルトランザクションコミットを使用できませんでした。

奇妙なことに、このエラーはすべての実行で発生するわけではなく、7〜8回の実行で1回発生します。

今私の質問は

  1. XA対応のトランザクションを使用する場合、Bean管理のトランザクションの重要性は何ですか?
  2. なぜそれはすべての実行で遭遇しないのですか?

ありがとう。

以下はコードです-

DataObject.updateDataAndReturnCount(" UPDATE EOD_Trn_BatchProcess SET iJobNo = ?, szParameters = ?  WHERE iProcessSeqNo = ? ", conn, new String[]{null, strParameters, (String)mapParameters.get("__PROCESS_SEQ_NO")});
conn.commit();

String strStatement = "{? = call submitProcAsJob(?, ?)}";
//String strStatement = "begin ? := submitProcAsJob(?, ?); end;";
CallableStatement pStmt = conn.prepareCall(strStatement);
pStmt.registerOutParameter(1, OracleTypes.NUMBER);
pStmt.setObject(2, strJobName);
pStmt.setObject(3, strInstanceNo);
pStmt.execute();
vString strJobNo = pStmt.getString(1);
vpStmt.close();

DataObject.updateData(" UPDATE EOD_Trn_BatchProcess SET iJobNo = ?, szParameters = ?  WHERE iProcessSeqNo = ? ", conn, new String[]{strJobNo, strParameters, (String)mapParameters.get("__PROCESS_SEQ_NO")});
conn.commit();

ここでは、ジョブの送信が失敗した場合でも、呼び出し中に使用されるパラメーターを保存したいので、最初のコミットが必要です。

4

2 に答える 2

1

例外の理由は、グローバル トランザクションの下で手動で commit()/rollback を呼び出すことができないためです。ロールバックのマークを付けることができるだけです。次の 3 つのオプションがあります。

  1. ejb-jar.xml/weblogic-ejb-jar.xml に依存する例外をスローします。デフォルトは、トランザクションがロールバック用にマークされているすべての RuntimeException です。

  2. CheckedException の場合、または必要なときにいつでも EJBContext.setRollbackOnly() メソッドを呼び出します。

  3. 同じトランザクションのすべてのリソースで上記のいずれも起こらなかった場合、遅かれ早かれトランザクション マネージャーによってコミットされます。

トランザクション マネージャーは、トランザクションの commit()/rollback() を担当するため、さまざまなリソース (たとえば、2 つの orce db) と連携する機会があります。キーワードを gooble して詳細を確認できます。 「2 フェーズ トランザクション」または「グローバル トランザクション」、ここに私が見つけたものがあります: グローバル トランザクション

あなたの質問について

  1. XA 対応トランザクションを使用する場合、Bean 管理トランザクションの重要性は何ですか?

    ejb-jar.xml の transaction-attribute でトランザクションの伝播が有効になっている場合、Bean 管理のトランザクションは「グローバル トランザクション」です。グローバル トランザクションでは、データソースで XA が有効になっている必要があります。つまり、jdbc ドライバー自体が oracle.jdbc.xa.client.OracleXADataSource などの XA 種類のドライバーであるか、XA が有効になっているシン ドライバー oracle.jdbc.OracleDriver です (2 つのシミュレーション段階的な取引ですが、実際の取引ではありません)

  2. すべての実行で遭遇しないのはなぜですか?

    理由はわかりませんが、ドライバーには、ルールが壊れているかどうかを確認するメカニズムがあると思います。または、トランザクション属性がSupportsに構成されているため、呼び出し元にトランザクションコンテキストがある場合、ejb はグローバルトランザクションの下にありますが、そうでない場合はそうではありません。

私の答えが役に立つことを願っています、頑張ってください!

于 2013-03-21T02:05:58.740 に答える
0

私は同じ問題に遭遇しました。ローカル トランザクションを自動コミット false に設定すると、問題は解決しました。

Connection.setAutoCommit(false)

2 フェーズ トランザクションを使用していると思いますが、最初のステップでコミットしないとどうなりますか?

于 2013-03-19T14:31:53.003 に答える