1

XA をネイティブにサポートしていないデータベースに XA サポートを追加するオープンソースの Java ライブラリはありますか? つまり、非 XA JDBC データソースをラップし、2 フェーズ コミットの背後で必要なコミット/ロールバックを処理しますか?

4

1 に答える 1

11

いいえ、それは不可能だからです。

XAが何を達成するように設計されているかを確認しましょう。これは、複数のリソースマネージャーにまたがるトランザクションのACIDプロパティを保証するためのコンセンサスプロトコルです。これを行うには、2フェーズコミットプロトコルを利用します。トランザクションマネージャーは各リソースマネージャーを準備してから、それぞれをコミットします。

プロトコルが正しく機能するためには、データベースなどのリソースマネージャは、準備段階で特定の保証を行う必要があります。これには、a)コミットフェーズ(「分離」)まで他のプロセスに変更を表示しない、b)準備とコミットの間にクラッシュした場合でも、必要に応じてコミット時に更新を実行できるようにする(「耐久性」)、およびc)さまざまなトランザクションで操作されるデータが、約束された整合性プロパティを示すことを確認します。現実的には、それを実装する唯一の方法は排他的ロックです。ほとんどの操作でMVCCまたは他の手法を使用するリソースマネージャー(pgsqlやoracleなど)でさえ、準備時に排他ロックを取得します。

db内部にアクセスできないと、ロックを取得して接続間で保持することはできません。したがって、トランザクション要件を満たすことができるコードを作成することはできません。したがって、データベースエンジンの上にXAを階層化する必要はありません。ベイクインする必要があります。

でも...

XAの動作のいくつかの側面を偽造することができます。正確なアプリケーション要件によっては、これにより有用なソリューションを作成できる場合があります。

まず、Last Resource Optimization(別名Last ResourceCommitOptimizationまたはLastResourceGambit)を使用して、単一の非XA、つまり1つのフェーズリソースを1つ以上の実際のXAリソースを持つXAトランザクションに参加させることができます。処理順序の最後に1つのフェーズのリソースを注文することで、ほとんどのシナリオでXAのように動作するものを実現できます。実行の特定の時点でクラッシュが発生すると、ひどく壊れます。そのため、データ調整コードをカスタムで作成するか、その不測の事態を処理するために人間に頼る必要があります。データのセマンティクスに応じて、魅力的なオプションである場合とそうでない場合があります。

次に、セマンティックレプリケーションのように動作するカスタムドライバーを実装できます。準備時にSQL操作のシーケンスをログに記録しますが、実際にはコミットフェーズまでデータベースに適用しません。これは、アプリケーションレベルで分離されたトランザクション更新に対して機能しますが、同時実行制御をデータベースに依存している場合は機能しません。たとえば、準備フェーズとコミットフェーズの間で競合する更新に他の何かが忍び込んだために、コミットが失敗する場合があります。外部ロックマネージャーを使用することもできますが、それはカスタムドライバーがデータベースと通信する唯一のものである場合に限られます。そのロックマネージャーに気付いていないクライアントがやってくるとすぐに、すべての賭けはオフになります。

最後に、そのモデルを反転して、XAで報酬ベースのトランザクションを使用できます。このモデルでは、準備時に更新を適用し、必要に応じてロールバックフェーズでそれらの効果を元に戻すために追加の操作を適用します。これには2つの欠点があります。準備とコミットの間に分離がないため、同時操作がtxの時期尚早にコミットされた値を読み取り、後でロールバックする可能性があります。また、ビジネスロジックによっては、適切な報酬ステートメントを生成するのは簡単ではありません。可能であっても、クラッシュシナリオでも適切に実行されるようにするには、非常に多くの複雑な配管が必要です。

現実的には、おそらくLRCOに制限されています。これは、ほとんどのトランザクションマネージャーによってすぐにサポートされます。他のオプションを正しく実行するには、トランザクションに関する十分な専門知識が必要であり、開発/テストのオーバーヘッドは通常正当化されません。LRCOが機能しない場合は、率直に言って、XAの必要性を回避するためにアプリを再設計する方が簡単です。

于 2011-11-28T16:30:56.237 に答える