この記事は主に Java 分散トランザクションについて詳しく説明したもので、非常に優れていると思いますので、参考として共有します。エディターをフォローして見てみましょう
2. 分散トランザクションが生成される理由
2.1. データベースサブデータベースとサブテーブル
2.2. SOA を適用する
上記の 2 つの状況は見た目が異なりますが、どちらも操作するデータベースが増えるため、本質的には同じです。
いわゆるアトミック性とは、トランザクション全体のすべての操作が完了するか、まったく実行されず、中間状態が存在しないことを意味します。トランザクションの実行中にエラーが発生した場合、すべての操作がロールバックされ、トランザクション全体がまったく実行されなかったかのようになります。
トランザクションの実行では、A が 500 元を持ち、B が 300 元を B に正常に送金する場合を例に挙げます。トランザクションの場合、同時実行性がどれほどであっても、何が起こっても、トランザクションが正常に実行される限り、最終的にアカウント A は 450 元、アカウント B は 350 元でなければなりません。
いわゆる分離とは、トランザクションが互いに影響を与えず、あるトランザクションの中間状態が他のトランザクションから認識されないことを意味します。
いわゆる永続性とは、単一のトランザクションが完了した後、停電が発生したり、このようにシステムがダウンしています。
最も古典的なシナリオは、購入者の口座からの引き落としと販売者の口座への追加を同時に行うことです。トランザクション内で実行されると、すべて成功するかすべて失敗します。購入者のアカウントは購入者センターに属し、購入者のデータベースに対応しますが、販売者のアカウントは販売者センターに属し、販売者のデータベースに対応するため、分散トランザクションを導入する必要があります。
購入者が電子商取引プラットフォームで注文を行う場合、多くの場合、2 つのアクションが必要になります。1 つは在庫の差し引き、もう 1 つは注文のステータスを更新することです。データの一貫性を確保するには、分散トランザクションを使用する必要があります。
XA は Tuxedo によって提案された分散トランザクション プロトコルです。 XA は、トランザクション マネージャーとローカル リソース マネージャーの 2 つの部分に大別されます。ローカル リソース マネージャーはデータベースによって実装されることが多く、Oracle や DB2 などの商用データベースはすべて XA インターフェイスを実装しており、トランザクション マネージャーはグローバル スケジューラーとして機能し、各ローカル リソースの送信とロールバックを担当します。分散トランザクションを実装する XA の原理は次のとおりです:
一般に、XA プロトコルは比較的単純で、商用データベースが XA プロトコルを実装すると、分散トランザクションを使用するコストも比較的低くなります。ただし、XA には致命的な欠点もあります。つまり、特にトランザクション注文リンクでは同時実行量が非常に多く、XA は同時実行性の高いシナリオには対応できません。 XA は現在、商用データベースでは理想的にサポートされていますが、mysql データベースではあまり適切にサポートされていません。mysql の XA 実装では準備フェーズのログが記録されず、アクティブ データベースとスタンバイ データベースの間でデータを切り替えると、アクティブ データベースとスタンバイ データベースの間でデータの不整合が発生します。また、多くの nosql は XA をサポートしていないため、XA のアプリケーション シナリオは非常に限られています。
いわゆるメッセージ トランザクションは、メッセージ ミドルウェアに基づく 2 段階の送信であり、本質的には、ローカル トランザクションとメッセージ送信を分散型に配置します。トランザクションでは、ローカル操作が成功し、外部メッセージが成功するか、または両方が失敗することが保証されます。オープンソース RocketMQ は、この機能をサポートしています。具体的な原則は次のとおりです。メッセージミドルウェアにメッセージを送信します2. メッセージミドルウェアは予備メッセージを保存し、成功を返します
3. A はメッセージミドルウェアにコミットメッセージを送信します事務。上記の 4 つのステップについて、各ステップでエラーが発生する可能性があります。1 つずつ分析してみましょう: ステップ 1 でエラーが発生すると、トランザクション全体が失敗し、A のローカル操作は実行されません。
ステップ 2 エラーが発生した場合、トランザクション全体が失敗し、A のローカル操作は実行されません
ステップ 3 でエラーが発生しました。この時点で、準備メッセージをロールバックする必要があります。ロールバックするにはどうすればよいですか?答えは、システム A がメッセージ ミドルウェアのコールバック インターフェイスを実装し、トランザクション A が正常に実行されたかどうかを確認するためにコールバック インターフェイスを継続的に実行し、失敗した場合は準備されたメッセージがロールバックされるということです。
ステップ 4 でエラーが発生しました。この時点で、A のローカル トランザクションは成功しています。メッセージ ミドルウェアは A をロールバックする必要がありますか?答えは「いいえ」です。実際、メッセージ ミドルウェアは、コールバック インターフェイスを通じて、A が正常に実行されたことを確認できます。実際には、メッセージ ミドルウェアが独自にメッセージを送信する必要はありません。これにより、メッセージ トランザクション全体が完了します
メッセージ ミドルウェアに基づく 2 段階コミットは、分散トランザクションをメッセージ トランザクション (システム A のローカル操作 + メッセージ送信) + ローカル操作に分割するために、同時実行性の高いシナリオでよく使用されます。システム B の操作はメッセージによって駆動されます。メッセージ トランザクションが成功する限り、A 操作は成功する必要があり、この時点で B はメッセージを受信して実行する必要があります。ローカル操作が失敗した場合、B 操作が成功するまでメッセージが再配信されます。このようにして、A と B の間の分散トランザクションが偽装されます。原則は次のとおりです。
上記のソリューションは A と B の操作を完了できますが、A と B は厳密には一貫性がありませんが、ここではパフォーマンスの大幅な向上と引き換えに一貫性を犠牲にしています。もちろん、この種のゲームプレイにもリスクが伴います。B が実行に失敗し続けると、一貫性が損なわれます。これをプレイするかどうかは、ビジネスがどの程度のリスクを負担できるかによって決まります。
いわゆる TCC プログラミング モードも、2 フェーズ サブミッションの変形です。 TCC は、ビジネス ロジック全体を試行、確認、キャンセルの 3 つの部分に分割するプログラミング フレームワークを提供します。オンライン注文を例にとると、Try ステージで在庫が差し引かれ、確認ステージで注文ステータスが更新され、注文の更新が失敗した場合はキャンセル ステージに入り、在庫が復元されます。つまり、TCC はコードを通じて 2 段階の送信を人為的に実装しています。異なるビジネス シナリオで記述されたコードは異なり、そのため、このモデルはうまく再利用できません。
分散トランザクションは、基本的に複数のデータベース内のトランザクションを統合制御するもので、制御の強度に応じて、制御なし、部分制御、および完全制御に分類できます。制御なしとは、分散トランザクションを導入しないことを意味します。部分制御とは、前述のメッセージ トランザクション + 最終整合性を含むさまざまなバリアントの 2 フェーズ コミットを意味し、完全な制御は、2 フェーズ コミットを完全に実現することを意味します。部分制御の利点は、同時実行性とパフォーマンスが非常に優れていることです。欠点は、完全制御ではパフォーマンスが犠牲になり、最終的にどの方法を使用するかはビジネス シナリオによって異なります。技術者として、テクノロジーはビジネスに役立つということを忘れてはなりません。異なるビジネスに合わせてテクノロジーを選択することも非常に重要な能力です。
以上がJAVA分散トランザクションについての深い理解の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。