この記事はWeChatの公開アカウント「Source Code Interest Circle」から転載したもので、著者はMa Longtaiです。この記事を転載する場合は、Source Code Interest Circle の公開アカウントにご連絡ください。 ローカルトランザクションは仕事で最もよく使用されますが、単一のプロジェクトをSOAとマイクロサービスに分割すると、分散トランザクションのシナリオが関係します。 この記事では主に分散トランザクションについて説明し、2PC および 3PC アルゴリズムについて詳しく説明します。最後に、分散トランザクションをよりよく理解できるようにデモを使用します。記事のディレクトリ構造は次のとおりです
取引とは何か トランザクションは、データベース操作の最小の作業単位であり、分割できない一連の操作であり、単一の論理的な作業単位として実行される一連の操作です。これらの操作はシステム全体に送信され、すべてが実行されるか、まったく実行されないかのいずれかになります。 トランザクションには、アトミック性、一貫性、独立性、永続性という 4 つの特性があり、これらはトランザクションの ACID 特性と呼ばれます。 トランザクションの ACID プロパティを確保するにはどうすればよいですか?
この記事では、主に分散トランザクション 2PC と 3PC について紹介します。 redo、undo log、mvcc、lock に関する内容は後ほど詳しく紹介します。 以前は、アプリケーションは単一のプロジェクトだったので、ローカル トランザクションと呼ばれる単一のデータベースを操作していました。ローカル トランザクションの ACID は、通常、私たちが仕事でよく使用する MySQL データベースなどのデータベース レベルでサポートされます。 通常、MySQL クライアントを操作すると、MySQL は暗黙的にトランザクションを自動的にコミットするため、日常業務ではトランザクションの作成、送信、ロールバックなどの操作を手動で記述する必要はありません。ロックや MVCC などの機能をテストする場合は、複数のセッションを作成し、begin、commit、rollback などのコマンドを使用して異なるトランザクション間のデータをテストし、実行結果が目的と一致しているかどうかを確認できます。 通常、プロジェクト コードを開発するときは、Spring のカプセル化されたトランザクションを使用するため、データベース トランザクションのコミットやロールバックなどのメソッドを手動で記述することはありません (一部の場合を除く)。ここでは、ネイティブ JDBC を使用してサンプル コードを記述し、トランザクションを通じて ACID の 4 つの主要な特性を確保する方法を理解できるようにします。
データベース操作を実行するたびに、トランザクションの作成、コミット、ロールバックなどの繰り返しメソッドを記述する必要があると想像してください。痛くないですか? Spring はどのようにしてトランザクションの管理を自動的に支援できるのでしょうか? Spring プロジェクトでは、通常、トランザクションを管理するために、プログラムによるトランザクションと宣言的なトランザクションという 2 つの方法を使用します。 インターフェース メソッドに @Transactional アノテーションを追加するか、AOP を使用してアスペクト トランザクションを構成することにより、Spring を使用してプロジェクト内のトランザクションを管理します。実際、これら 2 つのメソッドは似ていますが、@Transactional の方が粒度が細かい点が異なります。原則として、どちらの方法も AOP に依存します。例を見てみましょう。
TransactionalService は、Spring によってプロキシ オブジェクトとして作成され、コンテナーに配置されます。作成されたプロキシオブジェクトは次のクラスと同等です
サンプル コードは簡潔で明確に見えますが、実際のコード生成コードははるかに複雑です。トランザクション マネージャーに関しては、Spring は PlatformTransactionManager インターフェースを提供します。このインターフェースには、次の 2 つの重要な実装クラスが含まれています。
これら 2 つの実装クラスを通じて、私たちが通常使用するプログラム トランザクションと宣言型トランザクションは、ローカル トランザクション管理の実装に依存していることがわかります。 Spring は分散トランザクションもサポートします。 JTA 分散トランザクションのサポートについてはオンラインで多くの情報が提供されているため、ここでは詳細には触れません。 分散トランザクションとは何か 私たちは日常のビジネスコードで常にローカルトランザクションを使用しており、理解するのは難しくありません。しかし、サービス指向アーキテクチャ (SOA) とマイクロサービスの普及により、単一のビジネス システムが複数のシステムに分割されるようになりました。業務システムの変化に対応するため、データベースも業務ごとに分割されています。 例えば、学校管理システムを例にとると、学生サービス、コースサービス、教師サービスなどに分割され、データベースも複数のライブラリに分割されます。このような場合、サーバーにさまざまなサービスをデプロイすると、次のサービス呼び出しが発生する可能性があります。 ServiceA は、ローカル トランザクションを実行するためにデータベースを操作する必要があり、同時にトランザクション呼び出しを開始するために ServiceB と ServiceC を呼び出す必要があります。 3 つのサービスのトランザクションが同時に成功または失敗することを保証するにはどうすればよいでしょうか?ユーザーが開始したトランザクションの ACID 特性をどのように保証するのでしょうか?これは間違いなく分散トランザクションのシナリオです。 3 つのサービスの単一のローカル トランザクションでは、要求全体のトランザクションを保証することはできません。 分散トランザクションのシナリオには多くのソリューションがあります。さまざまな分類から、強力な一貫性ソリューションと最終的な一貫性ソリューションが存在します。ソリューションには、2PC、3PC、TCC、信頼性の高いメッセージングなどが含まれます。 業界で広く使用されているソリューションには、Alibaba の RocketMQ トランザクション メッセージ、Seata XA モード、信頼性の高いメッセージ モデルなどがあります。ただし、分散トランザクションは必ず複数のデータベースを直接的または間接的に操作するため、分散トランザクションの使用によってパフォーマンスの問題という新たな課題も生じます。強力な一貫性のある分散トランザクションまたは補償ソリューションの最終的な一貫性を確保するためにパフォーマンスが低下すると、通常のビジネスにとってメリットよりもコストがかかることは間違いありません。 DTP モデルと XA 仕様 X/Open 組織は、分散トランザクション モデル (DTP) と分散トランザクション プロトコル (XA) を定義します。 DTP は次のモデル要素で構成されます。
DTP分散トランザクションモデルでは、次の図に示すように、基本コンポーネントにAP、TM、RMSを含める必要があります(CRMとCPがなくても可能です)。 XA仕様 XA 仕様の最も重要な機能は、RM (リソース マネージャー) と TM (トランザクション マネージャー) 間の相互作用インターフェイスを定義することです。 XA仕様は、2PC間の相互作用インターフェースを定義するだけでなく、2PCの最適化も行う。 DTP、XA、2PCの関係を整理する DTP は分散トランザクションのロール モデルを定義し、グローバル トランザクションの制御にはデータの一貫性を確保するために 2PC プロトコルの使用が必要であることを指定します。 2PC は Two-Phase Commit の略で、分散システム アーキテクチャ内のすべてのノードがトランザクション処理中に原子性と一貫性を保証できるようにするために、コンピュータ ネットワーク、特にデータベース分野で設計されたアルゴリズムです。同時に、2PC は分散システム データの一貫性を確保するための一貫性プロトコルとしても考えられています。 XA 仕様は、X/Open 組織によって提案された分散トランザクション処理仕様です。 XA 仕様は、上図の RM と TM 間の相互作用である 2PC (2 フェーズ コミット プロトコル) に必要なインターフェイスを定義します。 2PC と XA は最も混同されやすいです。 DTP モデルで定義された TM と RM 間の通信用インターフェース仕様を XA と呼び、X/Open が提案する XA 仕様 (コアは 2PC アルゴリズムに依存) に基づくリレーショナル データベース (MySQL など) を XA ソリューションと呼ぶことがわかります。 2PCコンセンサスアルゴリズム アプリケーション (AP) が複数の分散ノードにまたがる必要があるトランザクション操作を開始すると、各分散ノード (RM) はトランザクション操作の結果が成功したか失敗したかを認識しますが、他の分散ノードの操作結果を取得することはできません。トランザクション処理の ACID 特性を確保するには、分散実行ロジックを均一にスケジュールする「コーディネーター」(TM) と呼ばれるコンポーネントを導入する必要があります。 コーディネータは、全体的なトランザクションに参加している分散ノードの動作をスケジュールする責任があり、最終的にこれらの分散ノードがトランザクションをコミットするかロールバックするかを決定します。したがって、この考えに基づいて、2 フェーズ コミットと 3 フェーズ コミットという 2 つの分散一貫性アルゴリズム プロトコルが派生しました。 2 番目の段階は、準備段階と提出段階を指します。まずは準備段階で何が行われるのか見てみましょう。 2PC-準備フェーズ 2 フェーズ コミットの最初のフェーズは「投票フェーズ」とも呼ばれ、各参加者が次のトランザクション コミット ステップの実行を続行するかどうかを示すために投票します。
最初のフェーズのすべての参加者が成功応答を返すと、トランザクション コミット ステップが開始されます。そうでない場合、分散トランザクションは失敗として返されます。 MySQL データベースを例にとると、最初の段階では、トランザクション マネージャー (TM) が関係するすべてのデータベース (RM) に準備要求を送信します。リクエストを受信すると、データベースはデータの変更とログレコードの処理を実行します。処理が完了すると、トランザクションのステータスは「コミット可能」に変更され、最終的に結果がトランザクション プロセッサに返されます。 2PCコミットフェーズ コミット フェーズは 2 つのプロセスに分かれています。 1 つは、各参加者がトランザクション コミット プロセスを通常どおり実行し、各参加者が正常に投票したことを示す Yes 応答を返すことです。もう 1 つは、参加者の 1 つが実行に失敗し、応答なしまたはタイムアウトを返すと、分散トランザクションの実行が失敗したことを示すグローバル ロールバックがトリガーされることです。
トランザクションコミットを実行する コーディネーターがすべての参加者から Yes 応答を受け取った場合、トランザクション コミット操作が実行されます。
トランザクションの中断 いずれかのトランザクション参加者ノードがコーディネータに No 応答をフィードバックした場合 (ここでの No 応答は最初の段階を指すことに注意してください)、またはコーディネータが待機タイムアウト後にすべての参加者からフィードバック応答を受信しなかった場合、トランザクション中断プロセスが実行されます。
2PCの長所と短所
データの不整合: コーディネーターが第 2 フェーズですべての参加者にコミット要求を送信すると、コミット要求を送信する前にローカル ネットワークの異常が発生するか、コーディネーターがクラッシュし、一部の参加者のみがコミット要求を受信することになります。リクエストを受信した参加者はトランザクションをコミットしますが、その結果、データの不整合が発生します。 2PC のシンプルさと利便性により、上記のような同期ブロック、単一点障害、データの不整合などの状況が発生します。そこで、2PCをベースに改良を加え、3フェーズコミット(3PC)を実装しました。 2PC の使用には多くの制限があります。まず、データベースは XA 仕様をサポートする必要があり、パフォーマンスとデータの一貫性は良くありません。したがって、Seata は XA モードをサポートしていますが、メインモードは依然として AT モードです。 3PCコンセンサスアルゴリズム 3 フェーズ コミット (3PC) は 2 フェーズ コミット (2PC) の改良版であり、次の 2 つの新機能が導入されています。
3PC の詳細な提出プロセスについてはここでは説明しません。 2PC と比較した 3PC の最大の利点は、参加者のブロック範囲が縮小され、コーディネータの単一障害点の後でも合意に達し続けることができることです。 永続的なリソース ブロックの問題はタイムアウト メカニズムによって解決されますが、3PC には依然としてデータの不整合の問題が残ります。参加者が PreCommit メッセージを受信するときに、ネットワークが分割されている場合、コーディネータと参加者は正常に通信できません。この場合、参加者はトランザクションをコミットします。 2PC と 3PC を理解すると、どちらも分散システムにおけるデータの一貫性の問題を完全に解決できないことがわかります。 JDBC操作MySQL XAトランザクション MySQL は 5.0.3 以降で XA 分散トランザクションをサポートしており、InnoDB ストレージ エンジンのみがこれをサポートしています。 MySQL Connector/Jはバージョン5.0.0以降、XAを直接サポートしています。 DTP モデルでは、MySQL は RM リソース マネージャーに属しているため、MySQL は独自の単一のトランザクション ブランチのみを実行するため、ここでは MySQL が XA トランザクションをサポートするというステートメントは示しません。 JDBC を使用して、TM を介して複数の RM を制御し、2PC 分散トランザクションを完了する方法を示します。 ここではまず、GAV Maven バージョンを導入する必要性について説明します。これは、上位バージョン 8.x では XA 分散トランザクションのサポートが削除されたためです (おそらく誰も使用しないため)。
公式アカウントでは読みやすさを確保するため、複数行のコードを IDEA を通じて 1 行に統合しています。 IDEA に貼り付ける必要がある場合は、フォーマットするだけです。 XA プロトコルの基礎は 2PC コンセンサス アルゴリズムであるため、コードを読む際には、上記の記事で説明した DTP モデルと 2PC を参照して、エラーや実行結果を理解およびシミュレートできます。
結論 この記事では、ローカルトランザクションの 4 つの主要な特性を確保する方法、分散トランザクションの出力背景、および 2PC と 3PC が分散状況でデータの一貫性を解決できない理由について、図とテキストを使用して説明します。最後に、JDBC を介した 2PC の実行プロセスを示します。これを読めば、分散トランザクションに対する印象が深まると同時に、DTP、XA、2PC などのわかりにくい概念も明確に理解できるようになると思います。 これは、「分散トランザクション」コラムの第 1 章の冒頭です。今後は、メッセージ ミドルウェア、信頼性の高いメッセージング モデル、Seata XA モデルを通じて分散トランザクションを完了することに関する記事を完成させ、さまざまな実装方法の長所と短所をまとめ、適切なシナリオに合わせてさまざまな分散トランザクション ソリューションを選択する予定です。 著者は、学習するための最良の方法は実践することだと信じています。分散トランザクションを経験したことがない場合は、作成中のプロジェクトを通じて分散トランザクションのビジネス シナリオをシミュレートできます。これにより、印象が深まり、分散トランザクション ソリューションに関連する設計のアイデアをより深く理解できるようになります。 |
>>: 7つのオプション! Redis 分散ロックの正しい使用法について議論する
1か月前、シドニーが脱税で6555万3100元の罰金を科されたとき、自称メディアパーソンの倪おじさん...
v.ps には、KVM 仮想化を採用し、デフォルトで 1Gbps の帯域幅を持つオランダの大容量ハー...
1. スペース(ウェブサイトの魂が存在する場所)私たちの魂が体の中に保存される必要があるのと同じよう...
北京時間12月5日、外国メディアの報道によると、音楽共有サイトSoundCloudの共同設立者アレッ...
HostflyteのCN2 VPS(CN2 GT、片道)が20%オフで販売されています。国内の往路は...
垂直分野における AI 知能のレベルはまだ初歩的ですか?この認識は時代遅れです。アリババDAMOアカ...
UGVPS は、2.5g メモリ/80g ハードディスク/2T トラフィック/年間 45 ドルの特別...
[[249686]]自然の季節に合わせて、TMT 業界全体が急速に寒い冬に向かっています。プライマリ...
2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っています最近、多く...
HosthatchはスウェーデンでVPSクラウドサーバー事業を展開しており、デフォルトのアクセス帯域...
edgenat は最近、香港 cn2 VPS、韓国 cn2 VPS、米国 cn2 VPS のプロモー...
今日、私は「Baidu 推奨エンジン」という新しい用語を見ました。百科事典では、これはユーザーの現在...
[[419619]]クラウド コンピューティングが新しいテクノロジーを採用し続けるにつれて、コンピュ...
iprr(翔翔雲、登録商標)は現在、中秋節特別キャンペーンを実施しています。国産100Gbps高防御...
検索エンジンを通じてより多くのトラフィックを獲得する方法を検討している場合、キーワードはあなたの仕事...