この記事は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年にイノベーションを加速させる方法
周知のとおり、ウェブサイト最適化中のウェブサイトキーワードの安定性は、SEO担当者にとって非常に重要...
個人ウェブマスターとして、私はこれまでたくさんのウェブサイトを構築してきました。業界ウェブサイト、ゲ...
[51CTO.com からのオリジナル記事] 強力なデータ分析機能、高速で高同時実行のビジネス処理効...
2021 年までに、コンピューティング インスタンスとワークロードの 90% 以上がクラウド データ...
クラウド コンピューティングの 10 年以上にわたる発展の中で、私たちは IT インフラストラクチャ...
SEO の将来性については、ほとんどの人が 2 つの考え方を持っています。一方では、検索エンジン技術...
Apple は最近、Xserve サーバー製品のアップグレード版を発表しました。新しい「Nehale...
chicagovps プロモーションがまたやって来ました。興味ありますか? !特価サーバー:ロサンゼ...
韓国の無制限トラフィック VPS は非常に人気があります。主な理由は、韓国の VPS は登録不要、高...
月収10万元の起業の夢を実現するミニプログラム起業支援プラン現在、多くの企業が SEO の最適化とプ...
現在、cubecloud ではすべての VPS に対して 12% 割引のプロモーションを実施しており...
クラウド コンピューティングは、企業の IT に新たなビジネス価値とエンドユーザーの利便性をもたらす...
中国証券監督管理委員会が発表した最新データによると、わが国の株式投資家の数は に達しています。この巨...
誰もが話題の合併や買収、製品のアップグレードについて話しているとき、かつてのデスクトップの覇者であっ...
外部リンクがウェブサイトの SEO パフォーマンスを向上させる方法はいくつかあります。1. ウェブサ...