1

私のアプリは障害から自動的に回復します。私はそれを次のようにテストします:

  1. アプリを起動
  2. 処理の途中で、アプリケーションサーバーホストを強制終了します(shutdown -r -f)
  3. ホストの再起動時に、アプリケーションサーバーが再起動します(Windowsサービスとして)
  4. アプリケーションが再起動します
  5. アプリケーションは処理を試みますが、前のセッションからのOracleDBの不完全な2フェーズコミットトランザクションによってブロックされます。
  6. 10〜30分後、DBは前のtxnを解決し、処理は正常に続行されます。

これより速く処理を続けるために必要です。私のDBAは、ステートメントの前に接頭辞を付ける必要があるとアドバイスしています

ALTER SESSION ADVISE COMMIT;

しかし、彼はこれを行うことでデータが失われる可能性についての保証や詳細を私に与えることはできません。

幸いなことに、問題のステートメントはdatetime値をSYSDATE1秒ごとに更新するだけなので、データが破損した場合、上書きされるまで1秒未満続きます。

しかし、私の質問に。上記のステートメントは正確に何をしますか?Oracleを使用すると、データ同期の問題をどのように解決しますか?

4

1 に答える 1

3

シナリオにおける「ローカル」データベースと「リモート」データベースの役割を明確にできますか。

通常、マルチデータベーストランザクションは次のことを行います

  1. トランザクションを開始します
  2. データベースに変更を加えます
  3. 他のデータベースに変更を加える
  4. 他のデータベースを「コミットすることを約束する」ように取得します
  5. ローカルでコミット
  6. コミットするリモートデータベースを取得します

ステップ4が完了し、何かが失敗した場合、疑わしいトランザクションが発生します。一般的な方法は、リモートデータベースをバックアップして、コミットされているかどうかを確認することです。その場合、ステップ(5)が先に進みます。トランザクションのリモートコンポーネントをコミットできない場合、ローカルコンポーネントはロールバックされます。

あなたの説明は、別の魚のやかんであるアプリサーバーの障害に言及しているようです。あなたの場合、シナリオは次のようになります。

  1. アプリサーバーが接続を確立し、トランザクションを開始します
  2. アプリサーバーがコミットせずに停止する
  3. アプリサーバーが再起動し、新しいデータベース接続を確立します
  4. アプリサーバーは、新しい接続で新しいトランザクションを開始します
  5. 新しいトランザクションは、古い接続/トランザクションによって保持されているロックを待機して「スタック」します
  6. 20分後、接続切れが終了し、トランザクションがロールバックされます
  7. その後、新しいトランザクションが続行されます

この場合の解決策は、タイムアウトを短くして(たとえば、サーバーのsqlnet.oraのSQLNET_EXPIRE_TIME)、手動のALTER SYSTEM KILL SESSIONを使用して、古い接続をより迅速に切断することです。

于 2011-06-03T03:46:14.053 に答える