分散トランザクションの使い方を 5 分で説明します。とても簡単です!

分散トランザクションの使い方を 5 分で説明します。とても簡単です!

[[417838]]

インターネット上の分散トランザクションについては、実用的なものよりも理論の方が多いです。今日は、分散トランザクションを体験できる事例を紹介したいと思います。今日は理論についてはあまり話さないようにしましょう。今日の主役はシータです!

分散トランザクションには、CAP、BASE など、多くの理論が関係しています。多くの友人はこれらの理論を見るとすぐに落胆するので、今日は理論については話しません。デモを見て、コードを通じて分散トランザクションがどのようなものかを簡単に体験してみましょう。

1. Seataとは何ですか?

Seata は、高性能で使いやすい分散トランザクション サービスを提供することを目的としたオープン ソースの分散トランザクション ソリューションです。 Seata は、ユーザーに AT、TCC、SAGA、XA トランザクション モードを提供し、ユーザー向けのワンストップ分散ソリューションを作成します。

Seata は次の 4 つのトランザクション モードをサポートしています。

  • シータATモード

  • シータTCCモード

  • シータ・サーガ・モード

  • シータXAモード

Seata には 3 つのコアコンセプトがあります。

  • TC (トランザクション コーディネーター) - トランザクション コーディネーター: グローバル トランザクションとブランチ トランザクションのステータスを維持し、グローバル トランザクションをコミットまたはロールバックします。

  • TM (トランザクション マネージャー) - トランザクション マネージャー: グローバル トランザクションのスコープを定義し、グローバル トランザクションを開始し、グローバル トランザクションをコミットまたはロールバックします。

  • RM (リソース マネージャー) - リソース マネージャー: ブランチ トランザクション処理のリソースを管理し、TC と通信してブランチ トランザクションを登録し、ブランチ トランザクションのステータスを報告し、ブランチ トランザクションをコミットまたはロールバックします。

このうち、TC は別途展開されるサーバーであり、TM と RM はアプリケーションに組み込まれたクライアントです。

これらの概念を理解するだけで十分です。意味がわからなくても、Seata は使えます。これらを理解すれば、Seata の動作原理をよりよく理解できるようになります。

2. Seataサーバーを構築する

まずはSeataサーバーを構築しましょう。

Seataダウンロードアドレス:

  • https://github.com/seata/seata/releases

最新バージョンは1.4.2ですので、最新バージョンを使用します。

このツールを Windows または Linux にデプロイしても大きな違いはないため、便宜上、ここでは Windows に直接デプロイします。

まずバージョン 1.4.2 の zip アーカイブをダウンロードし、ダウンロード後に解凍して、conf ディレクトリ内の 2 か所を構成します。

1. まずfile.confファイルを設定します

TC のストレージ モードは、file.conf で設定されます。 TC には 3 つの保存モードがあります。

  • ファイル: スタンドアロンモードに適しています。グローバル トランザクション セッション情報はメモリ内で読み書きされ、ローカル ファイル root.data に保存されます。高性能です。

  • db: クラスター モードに適しており、グローバル トランザクション セッション情報は db を介して共有され、パフォーマンスは比較的低くなります。

  • Redis: クラスター モードに適しています。グローバル トランザクション セッション情報は、比較的パフォーマンスが優れている Redis を介して共有されます。ただし、Redis モードは Seata-Server 1.3 以上でサポートされており、パフォーマンスは高いものの、トランザクション情報が失われるリスクがあるため、開発者は事前に現在のシナリオに適した Redis 永続化構成を構成する必要があることに注意してください。

トラブルを回避するために、ここではファイル モードに設定し、トランザクション セッション情報がメモリ内で読み書きされ、永続性がローカル ファイルに書き込まれるようにします (以下を参照)。

db または redis モードを設定する場合は、次の関連情報を必ず入力してください。詳細は以下の通りです。

他に注意する必要があるのは、独自のデータベースのバージョン情報です。データベース接続を変更する場合は、実際の状況に応じて変更してください。 Seata は、MySQL5.x および MySQL8.x に対応するデータベース ドライバーを提供します (lib ディレクトリ内)。ドライバーを変更するだけです。

2. registry.confファイルを再構成する

registry.conf は主に Seata の登録センターを構成します。皆さんもよくご存知のEurekaを使用しており、構成は以下のとおりです。

ご覧のとおり、サポートされている構成センターは多数あります。私たちはユーレカを選びます。構成センターを選択した後は、構成センターに関連する情報を変更することを忘れないでください。

これで設定は完了ですが、まだ開始しないでください。まだ Eureka レジストリが必要です。

3. プロジェクト構成

次にプロジェクトを構成します。

Seata は非常に古典的なデモを公式に提供しています。このデモを直接見てみましょう。

公式ケースダウンロードアドレス: https://github.com/seata/seata-samples

ただし、ここでは多くのケースが混在しており、乱雑に見える可能性があります。さらに、ダウンロードする依存関係が多数あるため、依存関係のダウンロードが失敗する可能性が非常に高くなります。したがって、以下に示すように、公式アカウントのバックグラウンドでseata-demoに返信して、Songge によって整理されたケースを取得し、直接インポートすることもできます。

商品を注文する場合です。簡単に説明しましょう:

  • eureka: これはサービスレジストリです。

  • アカウント: ユーザーのアカウント情報 (主にアカウント残高) を照会/変更できるアカウント サービスです。

  • order: 注文を行うことができる注文サービスです。

  • ストレージ: 商品の在庫数量を照会/変更できる倉庫サービスです。

  • ビジネス: これはビジネスであり、ユーザーの注文はここで行われます。

この事例から何がわかるでしょうか?

ユーザーが注文をしたい場合、ビジネス内のインターフェースが呼び出され、ビジネス内のインターフェースは独自のサービスを呼び出します。サービスでは、まずグローバル分散トランザクションが開始され、次にストレージ内のインターフェースが feign を通じて呼び出されて在庫が差し引かれ、次に order 内のインターフェースが feign を通じて呼び出されて注文が作成されます (注文を作成すると、order は注文を作成するだけでなく、ユーザーのアカウントの残高も差し引きます)。在庫を差し引いて注文の作成が完了すると、ユーザーの残高と在庫数量が正しいかどうかが確認されます。ユーザー残高がマイナスの場合、または在庫数量がマイナスの場合、トランザクションはロールバックされます。それ以外の場合は、トランザクションはコミットされます。

この事件の具体的な構造は次の通りです。

このケースは典型的な分散トランザクションの問題です。ストレージと注文のトランザクションは異なるマイクロサービスに属していますが、同時に成功または失敗することを期待しています。

誰もがこの事件が何であるか理解したので、それを実行してみましょう。

まず、seata という名前のデータベースを作成し、上記のコードにある all.sql データ スクリプトを実行します。

次に、上記のプロジェクトを idea で開き、各プロジェクトの application.properties ファイルのデータ接続情報を以下のように変更します (Eureka は変更する必要はありません)。

Eureka を除く他の 4 つは変更する必要があります。

OK、設定が完了しました。

4. テストを開始する

まずはユーレカを起動します。

次に、他のサービスを開始することを忘れないでください。まず、2 番目のセクションで構成したサービスである Seata Server を起動します。 bin ディレクトリで、Windows の場合はダブルクリックし、Linux の場合は起動スクリプトを実行します。

最後に、残りの 4 つのサービスを個別に起動します。起動が完了すると、Eureka で関連情報を表示できます。

ご覧のとおり、すべてのサービスが登録されています。

次に、ビジネスで提供されている 2 つのテスト インターフェイスにアクセスします。

最初のテスト インターフェースは次のとおりです。

http://127.0.0.1:8084/purchase/commit

このインターフェースに対応するコードは、 io.seata.sample.controller.BusinessController#purchaseCommitです。この部分では、ユーザーU100000 30 C100000アイテムを購入したことをシミュレートします。各アイテムの価格は100 、アイテムの在庫は200 、ユーザーアカウントの残高は10000です。したがって、購入後、アイテムの在庫は170 、ユーザーアカウントの残高は7000なります。これは通常の購入状況です。

  1. @RequestMapping (値 = "/purchase/commit" 、生成 = "application/json" )
  2. パブリック文字列購入コミット() {
  3. 試す{
  4. businessService.purchase( "U100000" , "C100000" , 30 );
  5. } catch (例外 exxx) {
  6. exx.getMessage()を返します
  7. }
  8. 「グローバルトランザクションコミット」を返します
  9. }

このインターフェースを調整したら、データベースに移動して対応するデータを表示できます。

2 番目のテスト インターフェイスは次のとおりです。

http://127.0.0.1:8084/purchase/rollback

このインターフェースに対応するコードは、 io.seata.sample.controller.BusinessController#purchaseRollbackです。今回は、ユーザーが99999アイテムを購入することをシミュレートします。ユーザー アカウントの残高もアイテムの在庫も、この購入動作をサポートできません。したがって、このインターフェースへの呼び出しは最終的にロールバックされ、データベース内のデータは同じままになります。

  1. @RequestMapping ( "/purchase/rollback" )
  2. パブリック文字列購入ロールバック() {
  3. 試す{
  4. businessService.purchase( "U100000" , "C100000" , 99999 );
  5. } catch (例外 exxx) {
  6. exx.getMessage()を返します
  7. }
  8. 「グローバルトランザクションコミット」を返します
  9. }

これは分散トランザクションの例です。

ご興味があれば、こちらの公式事例もご覧ください。ここでは物事が非常に単純であることがわかります。次のメソッド ( io.seata.sample.service.BusinessService#purchase ) には、もう 1 つのアノテーションがあります。

  1. @グローバルトランザクション
  2. パブリックvoid購入(String ユーザー ID、String 商品コード、 int注文数) {
  3. storageFeignClient.deduct(商品コード、注文数);
  4. orderFeignClient.create(ユーザーID、商品コード、注文数);
  5. 有効なデータがある場合(){
  6. throw new RuntimeException( "アカウントまたは在庫が不足しています。ロールバックを実行してください" );
  7. }
  8. }

購入メソッドには、グローバル トランザクションを開始するための@GlobalTransactionalアノテーションが付けられています。内部の 2 つの通話はどちらも偽の通話であり、異なるサービスに対応しています。最後に、データチェックが実行されます。チェックが失敗した場合は例外がスローされます。メソッドが例外をスローすると、上記の実行されたコードはロールバックされます。

このプロジェクトの残りのコードはマイクロサービスの通常のコードなので、詳細には触れません。

5. 実施原則

Seata におけるこの分散トランザクションの原理について少しお話ししましょう。まずは写真を見てみましょう:

この図は上記のケースを非常にわかりやすく説明しています。一般的なプロセスは次のとおりです。

  1. TM、RM、TC という 3 つの概念がありますが、これらはすでに最初のセクションで紹介したので、ここでは繰り返しません。

  2. まず、ビジネスはグローバルな取引を開始します。

  3. 次に、ビジネスがストレージとオーダーを呼び出すと、両方とも TC にブランチ トランザクションを登録し、データベース操作の前にコミットします。

  4. ブランチ トランザクションが動作している場合、undo_log テーブルにレコードが送信されます。グローバル トランザクションがコミットされると、undo_log テーブル内のレコードはクリアされます。それ以外の場合は、テーブル内のレコードに基づいて逆補正(データを元の状態に戻す)が実行されます。

具体的には、上記のケースでは、トランザクションの送信は 2 つの段階に分かれており、プロセスは次のようになります。

フェーズ1:

  1. まず、ビジネスはグローバルな取引を開始します。このプロセス中に、TC に登録され、グローバル トランザクション ID である xid が取得されます。

  2. 次に、Business で Storage マイクロサービスを呼び出します。

  3. SQL を解析するには、SQL タイプ (UPDATE)、テーブル (storage_tbl)、条件 (commodity_code = 'C100000')、およびその他の関連情報を取得します。

  4. 事前クエリイメージ: 分析によって得られた条件情報に基づいてクエリ ステートメントを生成し、データを検索します。

  1. ビジネス SQL を実行します。つまり、実際のデータ更新操作を実行します。

  2. 裏面の画像をクエリします。表面の画像の結果に基づいて、主キーでデータを検索します。

  1. ロールバック ログの挿入: フロント ミラー データとバック ミラー データおよびビジネス SQL 関連情報からロールバック ログ レコードが形成され、UNDO_LOG テーブルに挿入されます。

branch_id と xid は、それぞれブランチ トランザクション (つまり、ストレージ自体のトランザクション) とグローバル トランザクション ID を表します。 rollback_info は、逆補正 (ロールバック) の基礎として使用される前の画像と次の画像の内容を保存します。このフィールドの値は JSON です。この JSON のより重要な部分を皆さんと共有したいと思います。

  • beforeImage: これは変更前のデータベース内のデータです。各フィールドの値を見ると、ID は 4、カウント値は 200 であることがわかります。

  • afterImage: 変更後のデータベース内のデータです。 id が 4 で、count 値が 170 であることがわかります。

  1. 送信する前に、ストレージは TC にブランチを登録します。つまり、storage_tbl テーブル内の主キー値が 4 であるレコードに対してグローバル ロックを適用します。

  2. ローカル トランザクション コミット: ビジネス データの更新と、前の手順で生成された UNDO LOG が一緒にコミットされます。

  3. 同様に、注文とアカウントも上記の手順に従ってデータを送信します。

上記の手順 1 ~ 10 は、データ送信の最初の段階です。

第二段階を見てみましょう。

第 2 段階では、コミットまたはロールバックの 2 つの可能性があります。

上記のケースを例に挙げてみましょう。

  1. @グローバルトランザクション
  2. パブリックvoid購入(String ユーザー ID、String 商品コード、 int注文数) {
  3. storageFeignClient.deduct(商品コード、注文数);
  4. orderFeignClient.create(ユーザーID、商品コード、注文数);
  5. 有効なデータがある場合(){
  6. throw new RuntimeException( "アカウントまたは在庫が不足しています。ロールバックを実行してください" );
  7. }
  8. }

注文時に在庫が差し引かれ、注文が作成されます。最終チェック中に、在庫がマイナスであるか、ユーザー アカウントの残高がマイナスであることが判明し、注文に問題があることが示されます。この時点では、例外がスローされ、注文がロールバックされる必要があります。それ以外の場合は、データが送信される必要があります。

具体的な操作は以下のとおりです。

ロールバック:

  1. TC からのブランチ ロールバック要求を受信すると、ローカル トランザクションが開始され、次の操作が実行されます。

  2. xid と branch_id を使用して、undo_log テーブル内の対応するレコードを見つけます。

  3. データ検証: 2 番目の手順で見つかったバックミラーを現在のデータと比較します。違いがある場合は、現在のグローバル トランザクションの外部のアクションによってデータが変更されたことを意味します。この状況は、構成戦略に従って処理する必要があります。

  4. 3 番目のステップでの比較が同じ場合は、undo_log 内の以前のイメージとビジネス SQL 情報に基づいてロールバック ステートメントが生成され、実行されます。

  5. ローカル トランザクションをコミットします。そして、ローカルトランザクションの実行結果(つまり、ブランチトランザクションのロールバックの結果)を TC に報告します。

提出する:

  1. TC からブランチ送信要求を受信すると、その要求は非同期タスク キューに配置され、送信が成功した結果がすぐに TC に返されます。

  2. 非同期タスク フェーズでのブランチ送信要求により、対応する UNDO LOG レコードが非同期かつバッチで削除されます。

つまり、トランザクションが正常にコミットされた場合、undo_log テーブルにはレコードは存在しません。テーブル内のレコードを確認したい場合は、トランザクションがコミットされる前に DEBUG を通じて確認することができます。

6. まとめ

ここまで話しましたが、シータの話はこれで終わりでしょうか?ダメダメ! ATモードのみです!さらに 3 つのモードがあり、それについては次の記事で紹介します。

まあ、これは単純な分散トランザクションです。まずは体験してみましょう!タイトルが「5 分で分散トランザクションを体験する」なのは、記事の中で原則も共有しているからです。ケースを実行して体験するだけであれば、5 分もあれば十分でしょう。信じられないなら、試してみてください!

<<:  ガートナー:世界のパブリッククラウド支出は2022年に4,800億ドルを超える

>>:  新たな大規模なクラウドコンピューティングの注文、アマゾンとマイクロソフトが再び「戦い」

推薦する

10gbiz: 米国+香港 CN2 GIA ルートのベアメタル サーバーは 58% オフ、米国+香港 CN2 GIA ルートのクラウド サーバーは 60% オフ

新年の初めに、10g.bizは米国と香港のcn2 giaラインにベアメタルサーバーを追加し、特別に4...

「お父さん、どこへ行くの?」を観て、マーケティングとプロモーションについて学びましょう

マンゴーTVの2013年最後の番組「パパ、どこ行くの?」は、年末に大ヒットとなった。有名人の父と息子...

草の根ウェブサイトが短命に終わる理由と解決策

10月23日、Baiduのアルゴリズムが更新されました。今回のBaiduシステムアルゴリズムのアップ...

ウェブサイト構築リソース: エンタープライズ ウェブサイト構築システムの無料ダウンロード (レスポンシブ テンプレート 1 セットを含む)

月収10万元の起業の夢を実現するミニプログラム起業支援プランMetInfo エンタープライズ ウェブ...

チャネル運用:資金が足りないときに商品をうまく運用する方法

資金不足は、多くのチャネル運用学生が直面する共通の問題です。大企業に勤めていない限り、大きな予算を獲...

Baidu 百科事典による検索エンジン最適化をどのように見ていますか?

百度百科事典は19日午後、最新の統計データを発表した。それによると、2012年、百度百科事典の総項目...

太極アシスタント事件から見るモバイルアプリ市場

12月22日の夜、脱獄チームevad3rsは、待望のiOS 7用の完璧な脱獄ツールをリリースした。し...

探索は喜びと不安をもたらす

Google の「ロボット」がインターネットの隅々までクロールして以来、検索エンジンは人々にとって欠...

グループ購入モデルをどのように革新すれば、収益性を高め、投資を引き付けることができるでしょうか?

2011 年に急成長を遂げた後、共同購入 Web サイトは 2012 年に重要な時期を迎えました。現...

登録ドメイン名を初年度 0.5 ドルで登録

register.com は 3 月下旬にドメイン名登録割引を発表しました。.com ドメイン名の初...

SEOの微妙な変化

少し前に、Aniu が北京の学者による「SEO の長年にわたる変化」という記事を共有し、私に深い感銘...

ナレッジアプリのゲーミフィケーション運用計画

知識支払いの時代では、知識の獲得はよりシンプルで便利になりました。学生でも会社員でも、多くの知識ベー...

hostmybytes-$7/1g メモリ/500 ハードディスク/3T トラフィック/フェニックス/ケベック

hostmybytes、設立年は分かりませんでしたが、ドメイン名は2007年に登録され、現在は2名で...

クラウドネイティブを構築し、変革を加速する

[51CTO.com オリジナル記事] 数年前、CIO/CTO が集まったとき、彼らは「あなたの会社...

2019 年のエッジ コンピューティングに関する 4 つの予測

エッジは新しいクラウドであると企業が理解し始めたため、2018 年を通じてエッジはホットな話題となり...