序文: ビジネスの急速な発展とビジネスの複雑性の増大に伴い、ほぼすべての企業のシステムはモノリシックから分散型、特にマイクロサービス アーキテクチャへと移行します。すると、必然的に分散トランザクションの問題に直面することになります。 1. 基本理論具体的な解決策を説明する前に、まず分散トランザクションに関係する基本的な理論的知識を理解しましょう。 送金を例に挙げてみましょう。A が B に 100 元を送金する必要がある場合、A の残高は -100 元、B の残高は +100 元である必要があります。送金全体は、A-100 と B+100 が同時に成功するか、同時に失敗することを保証する必要があります。さまざまなシナリオでこの問題を解決する方法を見てみましょう。 1.1 取引複数のステートメントをまとめて操作する機能をデータベーストランザクションと呼びます。データベース トランザクションにより、トランザクションのスコープ内のすべての操作が成功または失敗することを保証できます。 トランザクションには、
ビジネス システムが複雑ではなく、1 つのデータベースと 1 つのサービスでデータを変更して転送を完了できる場合は、データベース トランザクションを使用して転送ビジネスが正しく完了することを確認できます。 1.2 分散トランザクション銀行間送金業務は、典型的な分散トランザクションのシナリオです。A が銀行間で 分散トランザクションとは、トランザクション イニシエーター、リソースとリソース マネージャー、およびトランザクション コーディネーターが分散システムの異なるノードに配置されていることを意味します。上記の転送業務では、ユーザー 分散環境では、分散トランザクションは、可用性、パフォーマンス、および劣化したサービスのニーズを満たすために、一貫性と分離性の要件を軽減し、一方では BASE 理論に従います(BASE 関連の理論には多くのコンテンツが含まれるため、興味のある学生は BASE 理論を参照できます)。
同様に、分散トランザクションも ACID 仕様に部分的に準拠しています。
2. 分散トランザクションソリューション分散トランザクション ソリューションでは、完全な 2.1 2フェーズコミット/XA XA は、 XA は 2 つの段階に分かれています。
現在、 XA トランザクションは、1 つ以上のリソース マネージャー (RM)、トランザクション マネージャー (TM)、および
上記の転送を例にとると、正常に完了した XA トランザクションのシーケンス図は次のようになります。 いずれかの参加者 XA トランザクションの特徴は次のとおりです。
2.2 サガSaga は、このデータベース ペーパー 上記の転送を例にとると、正常に完了した SAGA トランザクションのシーケンス図は次のようになります。 Saga トランザクションの特徴:
この論文の SAGA をさらに学習したい場合は、SAGA の成功と失敗のロールバックの例や、さまざまなネットワーク例外の処理を含む DTM を参照できます。 2.3 TCCC TCC は 3 つの段階に分かれています。
上記の送金を例にとると、通常、金額は Try で凍結されますが差し引かれず、 正常に完了した TCC トランザクションのタイミング図は次のとおりです。 TCC の特徴は次のとおりです。
2.4 ローカルメッセージテーブルローカル メッセージ テーブル ソリューションは、もともと 一般的なプロセスは次のとおりです。 ローカル メッセージの書き込みとビジネス操作は、ビジネスとメッセージ送信の原子性を確保するために 1 つのトランザクションに配置されます。すべてが成功するか、すべてが失敗します。 フォールトトレランスメカニズム:
ローカル メッセージ テーブルの機能:
非同期で実行でき、後続の操作のためにロールバックする必要のないビジネスに適用可能 2.5 トランザクションメッセージ上記のローカル メッセージ テーブル ソリューションでは、プロデューサーは追加のメッセージ テーブルを作成する必要があり、ローカル メッセージ テーブルをポーリングする必要もあるため、ビジネス上の負担が大きくなります。 Alibaba のオープンソース トランザクションメッセージの送信と提出: メッセージを送信(半分のメッセージ) 通常の送信フローチャートは次のとおりです。 補償プロセス: トランザクション メッセージの特性は次のとおりです。
非同期で実行でき、後続の操作のためにロールバックする必要のないビジネスに適用可能 2.6 ベストエフォート通知通知の発信者は、特定のメカニズムを使用して、ビジネス処理の結果を受信者に通知するために最大限の努力を払います。具体的には以下が含まれます: 特定のメッセージ繰り返し通知メカニズムがあります。通知の受信者が通知を受け取っていない可能性があるため、メッセージを繰り返すための特定のメカニズムが必要です。 信頼性の高いメッセージの一貫性: 通知を開始する側は、メッセージが送信され、通知を受信する側に確実に送信されるようにする必要があります。メッセージの信頼性は、主に通知を開始する側によって保証されます。 ベスト エフォート通知: 通知の発信者は、ビジネス処理の結果を通知の受信者に通知するために最善の努力を払いますが、メッセージが受信されない場合があります。この場合、通知の受信者は、ビジネス処理の結果を照会するために発信者のインターフェイスを積極的に呼び出す必要があります。通知の信頼性は、通知の受信者に依存します。 解決策としては、ベストエフォート通知には以下が必要です。
ベスト エフォート通知は、ビジネス通知タイプに適用されます。たとえば、WeChat トランザクションの結果は、ベスト エフォート通知を通じて各販売者に通知されます。コールバック通知とトランザクション クエリ インターフェイスがあります。 2.7 ATトランザクションモードこれは、Alibaba のオープンソース プロジェクト Seata のトランザクション モードであり、Ant Financial では FMT とも呼ばれます。利点は、トランザクション モードが XA モードと同様に使用されることです。ビジネス側でさまざまな補償操作を記述する必要がなく、ロールバックはフレームワークによって自動的に完了します。欠点も XA と同様で、長いロックがあり、高同時実行シナリオに対応していません。パフォーマンスの観点から見ると、AT モードは XA よりも優れていますが、ダーティ ロールバックなどの新しい問題も発生します。 3. 例外処理分散トランザクションのあらゆるリンクで、ネットワーク障害やビジネス障害が発生する可能性があります。これらの問題に対処するには、分散トランザクションのビジネス側で、アンチエア ロールバック、べき等性、アンチハングの 3 つの機能を実装する必要があります。 3.1 異常事態以下では、TCC トランザクションを使用してこれらの例外を説明します。 空のロールバック: TCC リソースの Try メソッドを呼び出さずに第 2 段階の Cancel メソッドが呼び出された場合、Cancel メソッドはこれが空のロールバックであることを認識し、直接成功を返す必要があります。 その理由は、ブランチ トランザクションがサービス ダウンタイムまたはネットワーク異常にある場合、ブランチ トランザクション呼び出しは失敗として記録されるためです。このとき、Try フェーズは実行されません。障害が回復すると、分散トランザクションがロールバックされ、2 番目のフェーズの Cancel メソッドが呼び出され、空のロールバックが発生します。 べき等性: あらゆるリクエストによってネットワーク異常や重複リクエストが発生する可能性があるため、すべての分散トランザクション ブランチでべき等性を確保する必要があります。 サスペンション: 中断とは、分散トランザクションの場合、Try インターフェイスの前に第 2 段階の その理由は、RPC が分岐トランザクション try を呼び出すと、まず分岐トランザクションが登録され、その後 RPC 呼び出しが実行されるためです。このとき、RPC 呼び出しのネットワークが混雑していると、RPC がタイムアウトした後、TM は RM に分散トランザクションをロールバックするように通知します。ロールバックが完了した後、Try の RPC 要求が参加者に到達して実際に実行される可能性があります。 上記の問題をよりよく理解するために、ネットワーク異常のタイミング図を見てみましょう。
上記の複雑なネットワーク異常に対して、現在さまざまな企業が推奨している解決策は、ビジネス側が固有のキーを使用して関連する操作が完了したかどうかを照会し、完了した場合は直接成功を返すというものです。関連する判断ロジックは複雑で、エラーが発生しやすく、大きな業務負担を課します。 3.2 サブトランザクションバリアプロジェクト https://github.com/yedf/dtm では、サブトランザクションバリア技術が登場しました。この技術を使用すると、この効果を実現できます。概略図をご覧ください。 これらのリクエストはすべて、サブトランザクション バリアに到達すると、異常な場合はフィルタリングされ、正常な場合はバリアを通過します。開発者がサブトランザクションバリアを使用すると、上記の例外はすべて適切に処理されます。ビジネス開発者は実際のビジネスロジックに集中するだけでよくなり、負担が大幅に軽減されます。 サブトランザクション バリアは、ThroughBarrierCall と呼ばれるメソッドを提供します。そのプロトタイプは次のとおりです。
ビジネス開発者は、busiCall に独自の関連ロジックを記述し、この関数を呼び出します。 サブトランザクションバリアはTCC、SAGA、トランザクションメッセージなどを管理し、他の領域にも拡張できます。 3.3 サブトランザクションバリア原則サブトランザクションバリア技術の原理は、ローカルデータベースにブランチトランザクションステータステーブル
このメカニズムにより、ネットワーク異常に関連する問題が解決される
SAGA、トランザクションメッセージなどの場合もメカニズムは同様です。 3.4 サブトランザクションバリアの概要サブトランザクションバリアテクノロジーは、https://github.com/yedf/dtm によって最初に作成されました。その重要性は、シンプルで実装しやすいアルゴリズムを設計し、シンプルで使いやすいインターフェースを提供することにあります。これら 2 つの要素の助けにより、開発者はネットワーク例外の処理から完全に解放されます。 このテクノロジーは現在、yedf/dtm トランザクション マネージャーで使用する必要があります。SDK は現在、Go 言語と Python 言語の開発者が利用できます。他の言語向けのSDKも計画中です。他の分散トランザクション フレームワークの場合、適切な分散トランザクション情報が提供されていれば、上記の原則に従ってテクノロジを迅速に実装できます。 4. 分散トランザクションの実践先ほど紹介した SAGA トランザクションを例に、特定の分散トランザクションを完了するためのトランザクション フレームワークとして DTM を使用します。この例では Go 言語を使用します。これに興味がない場合は、記事の最後の概要に直接ジャンプできます。 4.1 SAGAトランザクションまずはユーザーの口座残高を調整するためのコアビジネスコードを書いてみましょう func qsAdjustBalance(uid int, amount int) (interface{}, error) { _, err := dtmcli.SdbExec(sdbGet(), "dtm_busi.user_account を更新し、balance を balance + ? に設定し、user_id を ? に設定、amount、uid) dtmcli.ResultSuccess、err を返します } 次に、具体的な順方向演算・補正演算処理関数を書いてみます。 app.POST(qsBusiAPI+"/TransIn", common.WrapHandler(func(c *gin.Context) (interface{}, error) { qsAdjustBalance(2, 30)を返す })) app.POST(qsBusiAPI+"/TransInCompensate", common.WrapHandler(func(c *gin.Context) (interface{}, error) { qsAdjustBalance(2, -30) を返す })) app.POST(qsBusiAPI+"/TransOut", common.WrapHandler(func(c *gin.Context) (interface{}, error) { qsAdjustBalance(1, -30) を返す })) app.POST(qsBusiAPI+"/TransOutCompensate", common.WrapHandler(func(c *gin.Context) (interface{}, error) { qsAdjustBalance(1, 30)を返す })) この時点で、各サブトランザクションの処理関数は正常であり、次にSAGAトランザクションが開かれ、分岐呼び出しが行われます。 req := &gin.H{"amount": 30} // マイクロサービス ペイロード // DtmServer は DTM サービスのアドレスです saga := dtmcli.NewSaga(DtmServer, dtmcli.MustGenGid(DtmServer)). // TransOut サブトランザクションを追加します。転送操作は url: qsBusi+"/TransOut"、逆操作は url: qsBusi+"/TransOutCompensate" です。 (qsBusi+"/TransOut", qsBusi+"/TransOutCompensate", req)を追加します。 // TransIn サブトランザクションを追加します。順方向操作は url: qsBusi+"/TransOut"、逆方向操作は url: qsBusi+"/TransInCompensate" です。 追加(qsBusi+"/TransIn", qsBusi+"/TransInCompensate", req) // saga トランザクションを送信します。dtm はすべてのサブトランザクションを完了し、すべてのサブトランザクションをロールバックします。err := saga.Submit() この時点で、完全な SAGA 分散トランザクションが記述されました。 成功した例全体を実行したい場合は、yedf/dtm プロジェクトの指示に従って環境を設定し、次のコマンドで saga の例を実行します。
4.2 ネットワーク異常の処理dtm に送信されたトランザクションで転送操作を呼び出すときに短時間の障害が発生した場合はどうすればよいですか? SAGA トランザクション プロトコルによれば、dtm は未完了の操作を再試行します。このとき、何をすればよいでしょうか?障害は、転送操作の完了後にネットワーク障害が発生したか、転送操作中にマシンがクラッシュした可能性があります。口座残高の調整が正しいことをどのように確認すればよいでしょうか? サブトランザクション バリア関数を使用して、複数回の再試行後に 1 回のみの成功した送信が行われるようにします。 処理機能を次のように調整します。 func sagaBarrierAdjustBalance(sdb *sql.Tx, uid int, amount int) (interface{}, error) { _, err := dtmcli.StxExec(sdb, "dtm_busi.user_account を更新し、balance を balance + ? に設定し、user_id を ? に設定、amount、uid) dtmcli.ResultSuccess、err を返します } func sagaBarrierTransIn(c *gin.Context) (インターフェース{}, エラー) { dtmcli.ThroughBarrierCall(sdbGet(), MustGetTrans(c), func(sdb *sql.Tx) (interface{}, error) を返します { sagaBarrierAdjustBalance(sdb, 1, reqFrom(c).Amount) を返します。 }) } func sagaBarrierTransInCompensate(c *gin.Context) (インターフェース{}, エラー) { dtmcli.ThroughBarrierCall(sdbGet(), MustGetTrans(c), func(sdb *sql.Tx) (interface{}, error) を返します { sagaBarrierAdjustBalance(sdb, 1, -reqFrom(c).Amount) を返します。 }) } ここでの この TransIn サービスを複数回呼び出すと、残高は 1 回だけ調整されます。次のコマンドを実行すると、新しいプロセスを実行できます。 4.3 ロールバックの処理銀行がユーザー2に金額を振り込む準備をしているときに、ユーザー2の口座に異常を発見し、失敗を返した場合はどうなりますか?転送操作が失敗を返すように処理機能を調整します func sagaBarrierTransIn(c *gin.Context) (インターフェース{}, エラー) { dtmcli.ResultFailure、nil を返す } トランザクション失敗の相互作用のタイミング図を示します。 ここで一つ問題があります。TransIn の順方向操作は何もせず失敗を返しました。このとき、 心配しないでください。以前のサブトランザクション バリア テクノロジにより、送信前に エラーを返す TransIn を次のように変更できます。 func sagaBarrierTransIn(c *gin.Context) (インターフェース{}, エラー) { dtmcli.ThroughBarrierCall(sdbGet(), MustGetTrans(c), func(sdb *sql.Tx) (インターフェース{}, エラー) { sagaBarrierAdjustBalance(sdb, 1, 30) を返します }) dtmcli.ResultFailure、nil を返す } 最終的な結果は、バランスはまだ良好であるということです 5. まとめこの記事では、分散トランザクションの基本的な理論をいくつか紹介し、よく使用される分散トランザクション ソリューションについて説明します。記事の後半では、トランザクション例外の原因、分類、および優れたソリューションについても説明します。最後に、実行可能な分散トランザクションの例を使用して、短いプログラムで以前に紹介した内容を説明します。 これで、MySQL と Golan の分散トランザクションに関する 7 つの古典的なソリューションに関するこの記事は終了です。分散トランザクションに関する 7 つの古典的なソリューションの詳細については、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: <td></td> タグの境界線スタイルがブラウザに表示されない問題の解決方法
>>: データ URI スキームを使用して Web ページに画像を埋め込む方法の紹介
この記事の例では、スターフラッシュ効果を実現するためのjsの具体的なコードを参考までに共有しています...
序文:インターネット技術の継続的な発展に伴い、MySQL 関連のエコシステムはますます充実し、ますま...
目次Vue 再帰コンポーネントドラッグイベント最近、Vue を使用して、ドラッグ可能なツリー構造図と...
また、多くの場合、メンテナンスのために Web サイトを少なくとも数分間オフラインにする必要がありま...
1. クエリプロセスプロセスリストを表示2. 対応するプロセスを照会し、IDを強制終了します。検証(...
プロジェクトシナリオ: 1. アップロードファイルの制限関数: 1. フロントエンド操作による異常な...
目次1. ホームページ制作1. ダウンロードアプリの制作2. ナビゲーションバーの制作3. カルーセ...
序文Nginxの組み込みモジュールは、同時リクエスト数の制限とリクエストのソースの制限をサポートして...
以下の情報はインターネットから収集したものです1. アンカーは、Web ページ作成におけるハイパーリ...
目次1 ユーザー変数の概要2 ユーザー変数の定義3 ユーザー変数の使用3.1 セットを通した例3.2...
公式ドキュメント: https://nginx.org/en/linux_packages.html...
今日、Alibaba Cloudからディスク警告通知を受け取りました。確認したところ、100Gのスペ...
この記事では、例を使用して、MySQL トリガーの概要、トリガーの作成方法、およびトリガーの使用上の...
目次序文問題の説明原因分析拡大する総括する序文最近、データの欠落やデータの損失に関するフィードバック...
Linux で大量のファイルを削除する効率をテストします。まず500,000個のファイルを作成する$...