マイクロサービス(マルチデータベース、クロスサーバ)分散トランザクションコンポーネントデザインの考え方(王小龍、2019年12月10日)

トランザクション:

まず、取引の予測不可能な数存在してもよいです。

第二に、同時に関連するすべてのトランザクションを調整する必要があります。

第三に、トランザクションは、異なるサーバーに分散することができます。

地元の事務の組み合わせを介して第4、分散トランザクションの実施、全体的なサービスにメッセージを渡すことによって達成上院へのインターフェイスと組み合わせる(組み合わせRedisのパブリッシュ・サブスクライブ・メカニズム、Redisの購読クロスサーバ公開を行うには、いずれかのコミットやロールバックの集団を終わりますコントロール)

-------------------------------------------------- -

まず、トランザクションは、メッセージング規則を購読します:

  サービスは、開始剤、関連当事者に分かれています。

  (一意のトランザクションIDを生成しながら)分散トランザクションを作成し、自動的に現在のサブスクリプションメッセージ分散トランザクションのテーマを監視する責任トランザクションオリジネータ、:DistributedTransaction_StatusReport_TransactionID

  メッセージのテーマは二つのパラメータに分割され、一方はRequestID一TransactionStatus、ターゲットサービスの状態の実装ということです。

  分散トランザクション内の他のサービスを呼び出すときに、各異なるサービス要求をRequestID生成しながら、トランザクションIDは、同じ時間をかけて送信されます。

  トランザクションは、インターフェイスを追加するための(マイクロAPIサービスは、予約されたトランザクションIDフィールドが分​​散されているトランザクションであるとサービス基本クラスを要求ヌルデフォルトまたは空、パス又は特定のインターフェイスの形で実行されるトランザクションのニーズは、唯一分散トランザクションを実装しましたIDの特定のパラメータ)

      実行時のその他のサービスには、裁判官は、トランザクションID、トランザクションベースのスケジューリング状況がありますが、WAITONEを行うには、タイムアウト処理を待つことになるコミットする前に、コミットされません。

      Redisのは、サブスクリプションの開始前に待機、トランザクションIDに関連付けられたサブスクリプション・メッセージは、メッセージは次のとおりです。DistributedTransaction_StatusCommit_TransactionID

      メッセージを聞いたとき、設定操作、タイムアウト終了を行うと、トランザクション操作を完了。

  Redisのメッセージには、3つの結果を持っている:

    メッセージのタイムアウトを:ロールバック

    メッセージ提出:提出

    メッセージのロールバック:ロールバック

    [関わらず、ロールバックのサービスやコミット、上記事項の購読中止メッセージする必要があります。]

   各サービスコールの結果を記録するための責任がトランザクションの作成者を、分散しない、サービス呼び出しが失敗したのディスカバリステージ、エラーがある、即時通知は、ロールバック、他のサービスの前に完全に送信されていない、フォローアップサービスが呼び出しを継続しなくなりました。

    すべてのサービスの作成者は、自らの業務後に実行される問題がないが確認され、様々なマシンに配布プッシュメッセージは、円形に提出します。

  ----------------------------------------------

  これまでのところ、分散トランザクションが完了しています。あなたがサービス、各地域の事務の調整を呼び出すときにマイクロのサービス間で多くの問題を解決するには。

第二に、デザイン:

  DistributedTransaction.Createは()//、各サービスのスケジューリング結果を分散トランザクションIDを生成し、またはその他のサービス呼び出しの取引レンジ、配布を使用した文言を考え、そしてチェック

  DistributedTransaction.SessionID //保存上記の呼び出しは、トランザクションIDを作成するために作成します。

  DistributedTransaction.Commit()分散トランザクションのコミットの//実装は、実際には、サブスクライブメッセージを送信するすべての機器の加入者へのRedisに提出されたニュース・リリース、です。

  DistributedTransaction.Rollback()//ロールバックは、分散トランザクションを実行します。また、Redisのへのロールバックメッセージをリリースしました。

  DistributedTransaction.AddServiceTransactionは({ServiceRequestID、TransactionStatus})//関連当事者との取引を追加し、ローカルトランザクションに関与したサービス、および他の状態レコード(待って、コミット、ロールバック)のためのいくつかのレコードがある、また、必要性を表明しますリクエストIDによって要求された各サービスに関連した、または提出し、作成者がステータスを示すメッセージを送信する可能性がある場合、ロールは、サービスをバックアップしています。

  サービスのトランザクションがバックをロールされているかどうかを決定するために使用さDistributedTransaction.HasRollbacks()//

  トランザクションが提出され発生するかどうかを決定するために使用DistributedTransaction.HasCommits(); //

  DistributedTransaction.WaitComplate()

  最終的に完了するのを待って、その後、提出する必要があり、待機することがある場合は、//、偽とみなさ問題の提出、トランザクションがある場合は、提出のすべてのは、彼らがすべてコミットするかのようにすべての状態は、提出された場合にのみ、成功したかどうか、ロールバックを決定するために使用(また、タイムアウトメカニズムを持っている必要があります)。

  //このメソッドは、最終的な結果を待ち、トランザクションの最終結果と記述情報を返しますが、失敗した部分のみ要求IDを記録し、地元の要求とサービスの関連付けIDを完了するように拡張することができます。


第三に、質問:

  三が実行されたのトランザクションに関与する三つの異なるサービスが存在すると仮定すると、トランザクションは、ニュースリリースを送信する前にバック状態をコミットまたはロールする場合1、トランザクションの追跡、無トラッキング機構は、上述しました

    (停電を想定)サービスは、メッセージを受信することができない、他の2件のサービスメッセージが正常に受信されたクラッシュ、その後、他の2つはサービスをコミットし、サービスA機が送信されていない場合ので、

    理論的には、前と取引が事業に関与していない後のデータから、テーブルの特定の影響を追跡することはありません、インパクトは、そのため、手動でロールバックを実行することはできません。

    しかし、理論的には、完了または一部の提出を完了したかどうかは明らかでは、分散トランザクションの開始剤の増加することを確認するために、ロールバックを増やすか、コミット、サービスノードと他の仕組みがあります。

    しかし、トランザクションは髪のクラッシュを開始したことを前提であれば?マシンは、トランザクションに提出されていないが、トランザクション他の3つのサービスが提出されていますか?理論的には、マシンの復旧後にローカル事務を遂行提出しなければなりません。

  2、タイムアウトの問題

    Redisのが原因の不確実性への自動ロールバックを達成するために、段階を待って、ディレクティブコミットまたはロールバックからのサービスを受けるために、そのためのタイムアウトを監視し、タイムアウトが比較的短い時間でなければなりませんが、フォローアップ待っています

    トランザクションの作成者だけでなく、サービスコールの数が必要、と、短い時間が異常にロールバックにつながる可能性があり、各サービスの実行推定の期間を決定することはできません。

    可能な場合は、同じ統合時間は、待機時間が最も時間のかかるサービスの実行時間であることを保証するために、より多くのサービス指向の並列実行を考慮する必要があり、すべてのトランザクションを制御可能な最短時間内に完了する必要があります。

  2.1、タイムアウトトリガーロールバック

    通知がサービスのロールバックが発生したことにより、送信された場合は、上記の設計のためには、ロールバックまた、作成者またはサービスに関連するバッチ実行を通知するために、自動ロールバックサービスの後にタイムアウトを待つことはありません。

第四には、問題を解決するために:

    上記機構は、非分散異常、サービス・トランザクションまたはマイクロシンクロールバック仮定の同期実行で解決することができる。急激なサーバ、クラッシュのRedisのケースをクラッシュされていません。

 

-------------------------------------------------- -

ここでは、いくつかのEF / LINQ2SQLクロスデータベーストランザクションコードを歩んで同様の原理と上記の原理を実現するが、ないクロスサーバシナリオが存在しない、ローカルの業務は、次のとおりでないカプセル化された、唯一の実験的なコード、本番環境での必要性に、それが推奨されますか集中制御のためのクラスパッケージを書くのですか、コントロールに差は、自動的に(コミットされていない)トランザクションのロールバック集中エラーを完了した、クロスデータベースを必要とするデータベースの数を区別しません。

VaRのDC =新しいのdatacontexts(0); 
        dc.Ztb_shopdict.Connection.Open(); 
        VARトランザクション1 = dc.Ztb_shopdict.Connection.BeginTransaction()。
        dc.Ztb_shopinfo.Connection.Open(); 
        VAR TRAN2 = dc.Ztb_shopinfo.Connection.BeginTransaction()。

        //事务是否成功的标记
        BOOL TransactionStatus =はtrue。
        試す
        { 
            dc.Ztb_shopdict.Transaction =トランザクション1。
            dc.Ztb_shopdict.Dict_SystemPara.InsertOnSubmit(新しいAPI.Domain.ztb_shopdict.Dict_SystemPara(){ShopID = 0、ParaKey = ""、ParaValue = "V"})。
            dc.Ztb_shopdict.SubmitChanges(); 
            試す 
            {
                dc.Ztb_shopinfo.Transaction = TRAN2を。
                dc.Ztb_shopinfo.Activity_Item.InsertOnSubmit(新しいAPI.Domain.ztb_shopinfo.Activity_Item(){Activity_Info_ID = 0、Activity_Price = 0、addActivity_Price = 0、イネーブル=真、firstActivity_Price = 0、levelId = 0、サービスID = 0、ShopID = 0 }); 
                dc.Ztb_shopinfo.SubmitChanges(); 
            } 
            キャッチ(例外例)
            { 
                tran2.Rollback()。
                //同时抛出错误、引起1回滚
                投げEX。
            } 
        } 
        キャッチ(例外例)
        { 
            TransactionStatus = FALSE; 
            transaction1.Rollback();
            Response.Writeを(ex.ToString())。
        } 

        (TransactionStatus)場合
        { 
            //すべてのトランザクションは、成功しているに沿って提出
                transaction1.Commit(); 
                tran2.Commit(); 
        }

  

 

おすすめ

転載: www.cnblogs.com/soleds/p/12015257.html