この記事はWeChatの公開アカウント「プログラマーjinjunzhu」から転載したもので、著者はjinjunzhuです。この記事を転載する場合は、プログラマーjinjunzhuの公式アカウントまでご連絡ください。 分散トランザクションのソリューションの中で、TCC は 2 フェーズ コミットの考え方を使用して分散トランザクションの最終的な一貫性を実現する古典的なモデルです。しかし、最近は TCC モードがちょっと嫌いになってきました。 TCCレビュー TCC とは何でしょうか? 従来の電子商取引システムを例にとると、顧客が製品を購入する場合、購入を完了するにはシステムが連携する 3 つのサービスが必要です。注文サービスは注文を増やし、在庫サービスは在庫を減らし、アカウントサービスは金額を減らします。以下のように表示されます。 上記の方法を使用し、各サービスが個別にトランザクションを送信すると、データの不整合が発生する可能性があります。 3 つのサービスは異なるデータベースを使用するため、アトミック操作ではありません。たとえば、注文サービスが正常に送信されたが、アカウント サービスが失敗した場合、データの不整合が発生します。 TCC の考え方は、2 フェーズ コミットを使用することです。試行フェーズでは、まず各サービスがリソースの予約を試行します。予約が成功した場合、トランザクションはコミット フェーズでコミットされます。サービス予約が失敗した場合、トランザクションはキャンセル フェーズでキャンセルされます。これには、3 つのサービスにコマンドを発行し、各サービスのブランチ トランザクション実行結果を取得するための調整ノードを追加する必要があります。 try フェーズは次の図で表されます。 試行フェーズ中に各サービスがリソースを正常に予約すると、次の図に示すように、調整ノードは各サービスにコミット コマンドを発行します。 すべてのサービスが正常にコミットされると、トランザクション全体が完了します。 コードの実装 コーディネーション ノードは、各分散トランザクションに xid と呼ばれるグローバル トランザクション ID を提供する必要があります。この ID は、各サービスのローカル トランザクションにバインドするために使用されます。アカウント サービスを例に、try/commit/cancel の 3 つのステージのコードを見てみましょう。 このコードは、ローカル トランザクションを処理するために jdbc を使用します。 try フェーズでは、接続を取得して connectionMap に保存します。キーはxidです。このように、コミット/キャンセルフェーズでは、接続が connectionMap から取り出され、コミット/ロールバックされます。 問題点 上記の TCC モードのコード実装に問題はありますか? サービスクラスター 下の図に示すように、注文サービス クラスターが 3 台のマシンにデプロイされ、try 要求が注文サービス 1 に送信され、commit 要求が注文サービス 2 に送信された場合、注文サービス 2 の connectionMap の値が xid=123 になるのはなぜでしょうか。注文サービスのローカル トランザクションをコミットできません。 したがって、接続を維持してトランザクションを実際に送信する場合、コーディネータ ノードは、同じ xid に対応する try/commit/cancel 要求が同じマシンに送信されるようにする必要があります。 登録センターを変革したり、ノードを調整してサービス リストを自ら管理するなどの解決策が必要です。前者は登録センターとビジネスコードを結合しますが、後者は登録センターを放棄することと同じです。 空の送信 登録センターと調整ノードの変革には多くの作業が必要です。他に方法はあるでしょうか?改善しましょう。ここで、ORM フレームワークは mybatis を使用します。コードは次のとおりです。 リソースは try フェーズで予約する必要があります。このコードがリソースを正常に予約した場合、ブランチ トランザクションは実際にコミットされています。コミット フェーズは単なる空のコミットであり、実質的な効果はありません。 もう 1 つの方法は、try フェーズで直接 true を返し、commit フェーズで実際にトランザクションをコミットすることです。 しかし、これらの方法は両方とも TCC の考え方に反しています。 冪等性 コーディネーションノードがタイムアウトで再試行するように設定されている場合、下の図に示す状況が発生します。注文サービス 1 は try メソッドを実行した後に失敗します。コーディネーション ノードは、正常な応答を受信しない場合は必ず再試行するため、注文サービスは try メソッドを繰り返し実行します。 この問題を回避するには、try/confirm/cancel メソッドに冪等ロジックを追加して、グローバル トランザクション xid に対応するローカル トランザクションの実行ステータスを記録する必要があります。 空のロールバック フレームワークを使用して TCC モードを実装すると、空のロールバックが発生する状況が発生します。 上図に示すように、注文サービス 1 ノードに障害が発生したため try メソッドは失敗しますが、グローバル トランザクションは開始されています。フレームワークはこのグローバル トランザクションを終了状態にプッシュする必要があるため、ロールバックするには注文サービスのキャンセル メソッドを呼び出す必要があります。その結果、注文サービスはキャンセル メソッドを無駄に実行します。 この問題を解決するには、try フェーズで xid に対応する分岐トランザクションの実行ステータスを記録し、cancel フェーズでこの記録に基づいて判断を行う必要があります。 サスペンション 上記で、seata の使用中に空のロールバックが発生することが説明されました。空のロールバックが発生した場合、キャンセル メソッドの実行後にグローバル トランザクションは終了します。ただし、ネットワークの問題により、注文サービスは再試行リクエストを再度受信します。 try メソッドの実行後、予約されたリソースは成功しますが、これらのリソースは解放できません。 この問題の解決策は、cancel メソッドで xid に対応するブランチ トランザクションの実行ステータスを記録し、try フェーズの実行時にブランチ トランザクションがロールバックされたかどうかを判断することです。 コード侵入率が高い TCC の try/commit/cancel はすべてビジネス コードに侵入します。べき等性、空のロールバック、および中断を考慮すると、コード侵入はさらに高くなります。 要約する TCC は分散トランザクションにおける非常に古典的なモデルですが、フレームワークの助けを借りても、コードの実装は比較的複雑です。 実際の使用では、サービス クラスター、空の送信、べき等性、空のロールバック、中断などの問題を考慮する必要があります。 ビジネス コードへの侵入性が高くなります。 |
<<: ハイブリッドクラウドの将来はどうなるのでしょうか? 3つのキーワード: エッジコンピューティング、自動化、クラウドネイティブ
>>: クラウド革命が2021年にイノベーションを加速させる方法
中国インターネットネットワークインフォメーションセンター(CNNIC)による2008年中国検索エンジ...
最近、多くの友人から、ウェブサイトを分析してウェブサイト診断レポートを書く方法を尋ねられました。実際...
人は風雨の中で成長し、経験は常に経験を通じて蓄積されます。ブログの改訂期間中、私は考えるための自由な...
「Invasion」はtap4funが開発・運営する3D戦略戦争ゲームです。2015年9月2日より全...
オープンなWeiboプラットフォームは、ゲームメーカー、KOL、関心のあるユーザーを結び付けます。現...
みなさんこんにちは。私はハルビン仮想および現実ウェブサイト設計です。最近、私は百度の調整、ランキング...
クラウド コンピューティングとデジタル フォレンジックは相互に浸透し続けており、「クラウド フォレン...
Cloudcone は、KVM 仮想化、ロサンゼルス MC データ センター、1Gbps 帯域幅を備...
VMware は本日、VMworld 2020 において、顧客があらゆるクラウド上であらゆるアプリケ...
まず最初に、これは SEO 初心者向けの記事であることを述べておきます。あなたが専門家であるか、専門...
昨日のWeiboコラムで更新ペースが落ちていると書きましたが、今日はインスピレーションを得るために記...
SEO 担当者として、私たちはバックエンドのトラフィックの問題にほぼ毎日注意を払っており、私たちが行...
A5ウェブマスターネットワーク(www.admin5.com)は4月30日、アリババが最近とても忙し...
2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っていますウェブサイ...
ほとんどのインタラクティブな Web サイトでは、まずユーザーが登録プロセスを完了する必要があります...