この記事は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年にイノベーションを加速させる方法
photonvps.com は、China Telecom および China Unicom との二...
2008 年は、母子向けウェブサイトが急速に発展した黄金期でした。一方では、伝統的な母子向け製品チェ...
Lisahost は、台湾 ISP IP/台湾住宅 IP/台湾ネイティブ IP、純粋な IP、Sca...
月給5,000~50,000のこれらのプロジェクトはあなたの将来です2018年10月3日から5日まで...
Virtono の無制限データ VPS が現在セール中です。サイト上のすべての VPS がプロモーシ...
SEO 担当者やウェブマスターは、本物の Baidu スパイダーと偽物の Baidu スパイダーを区...
Amazon EKS (Elastic Kubernetes Service) クラスターを使用する...
多くの人は、運営やプロモーションにおいて、低コストで拡大するためのグロースハックの手法を見つけること...
ウェブサイトの最適化に関しては、多くのウェブマスターは、ウェブサイトの全体的な方向性や SEO の基...
オリジナリティは常に大きな問題であり、より広い意味で言えば、インターネットの生態環境はますます悪化し...
IDC がコントロール パネルで 301 を実行できない、または疑似静的ルールの記述方法を尋ねている...
Baidu の最適化に注目しているウェブマスターは、Baidu が最近、ブラックリンクやリンク取引を...
ウェブサイトの最適化中に、偶然、大手女性化粧品サイトを見たのですが、そのロングテールコンテンツの多く...
[51CTO.comよりオリジナル記事] クラウドコンピューティング、ビッグデータ、モノのインターネ...
10月16日、「文化部公式Weiboアカウント」として認証された文化部の青色公式Weiboアカウント...