ACIDだけではないビジネス | JD Logistics Technical Team

1. トランザクションとは何ですか?

アプリケーションの実行中に、データベースとハードウェアに障害が発生したり、アプリケーションとデータベース間のネットワーク接続が切断されたり、複数のクライアントが同時にデータを変更したりすることで、予期しないデータ カバレッジの問題が発生する可能性があります。データの一貫性が保たれているため、トランザクションが 成立しました。

概念的には、トランザクションは、アプリケーションが複数の読み取り操作と書き込み操作を 1 つの論理ユニットに結合する形式です。これにより、コミットが成功したか、ロールバックが失敗したかにかかわらず、すべての読み取り操作と書き込み操作が 1 つの操作として実行されます。部分的な成功や部分的なものはありません。失敗。現在、ほぼすべてのリレーショナル データベースと一部の非リレーショナル データベースはトランザクションをサポートしています。 

1.1 酸

トランザクションは ACID を使用して安全な操作 ( AtomicityConsistencyIsolation 、およびDurability )を保証します。ACID の提案は、データベースのフォールト トレランス メカニズムの正確な用語を確立することを目的としていますが、異なるデータベースでは同じではないため、1 つずつ説明していきます。   

  • 原子性

アトミック性の定義の特徴は、トランザクションは分割できない作業単位とみなされなければならないこと、トランザクション全体のすべての操作はすべて正常にコミットされるか、すべて失敗してロールバックされるかのいずれかであり、一部だけを実行することは不可能であることです。彼ら。 


  • 一貫性

一貫性は ACID における「冗長」な存在です。アトミック性、分離性、永続性とは異なります。一貫性はアプリケーションの属性であり、他の 3 つはデータベースの属性です。アプリケーションは一貫性を確保するために原子性と分離に依存する場合がありますが、場合によっては、一貫性の保証がデータベースだけに依存しないことがあります。 

一貫性の具体例は、データに対するアプリケーションの制約に依存します。たとえば、会計システムでは、すべてのアカウントのトランザクション収益と支出のバランスがとれていなければなりません。トランザクションがバランスの取れた状態で開始された場合、トランザクションが実行されてコミットされた後もバランスは維持されます。概念的には、一貫性は常に確立する必要があるデータに対する一連の特定の制約です。これらの書き込みと変更のロジックはアプリケーションによって決定され、データベースはこれらの操作のみを担当するため、これはアプリケーションによって保証されます。 


  • 隔離

実際の作業では、ほとんどのデータベースは複数のクライアントによって同時にアクセスされるため、クライアントが同じデータを同時に変更することになり、同時実行性の問題が発生する可能性があります。以下の例に示すように: 

分離.png

User1 と User2 はデータベース内の操作カウンタを同時に増やす必要があり、各ユーザーはまず値を読み取り、1 を加算してから書き込みます。理論的には、カウンターの値は最終的に 44 になるはずですが、同時実行の問題により、最終的な値は 43 になります。

一般に、分離により、トランザクションが最終的にコミットされる前に、トランザクションによって行われた変更が他のトランザクションから見えなくなり、同時実行性の問題が解決されます。1 つのトランザクションが複数の書き込みを行う場合、もう 1 つのトランザクションはすべての書き込みを認識するか、何も認識しません。したがって、上記の例では、カウンターを変更するときに User2 が読み取る値は、User1 による変更後の結果 43 になり、さらに 1 を加算して最終結果 44 になる必要があります。 


  • 持続性

永続性とは、トランザクションが正常にコミットされ、ハードウェア障害やデータベースのクラッシュが発生した場合でも、書き込まれたデータは失われないことを保証するものです。単一ノード データベースでは、通常、データがハードディスクに書き込まれていることを意味します。または SSD; ノード データベースでは、耐久性とは、データが一部のノードに正常に複製されたことを意味する場合があります。ただし、ハードディスクとバックアップが破壊されれば、データを取得できるデータベースは当然存在しないため、完全な耐久性は存在しません 

2. 同時実行によるデータ不整合の問題

多くの場合、トランザクション間の操作オブジェクト間の競合、および同時トランザクション間の不確実なタイミング関係により、これらの競合関係のあるオブジェクトにさまざまな奇妙な結果が表示されます。   

2.1 ダーティライト

2 つのトランザクションがデータベース内の同じオブジェクトを同時に更新しようとします。前の書き込みがコミットされていないトランザクションの一部である場合、後続の書き込みによりコミットされていない値が上書きされます。この状況はダーティ書き込みと呼ばれます 

2.2 ダーティリード

A トランザクションがデータベースにデータを書き込んだが、A トランザクションがコミットまたは中止されておらず、別の B トランザクション クエリが開始された場合、B トランザクションは A トランザクション内のコミットされていないデータを参照できます。これはダーティ リードです 

トランザクション A がロールバックされると、トランザクション B がコミットされていないデータをデータベースに送信する可能性が高く、その結果生じる問題によりトラブルシューティングが困難になる状況を考えます。

2.3 反復不可能な読み取り

アリスが銀行に 1,000 ドルの預金を持っており、それぞれ 500 ドルの 2 つの口座に分割されている例を考えてみましょう。ここで、彼女の口座の 1 つから別の口座に 100 ドルを送金するトランザクションがあります。トランザクションの途中でアカウントの残高を確認すると、送金後の送信側アカウントの残高が 400 ドルであるのに対し、受信側アカウントの残高はまだ 500 ドルであることがわかります。アリスにとって、彼女のアカウントには合計で 900 ドルしかないように見えますが、送金された 100 ドルはどこからともなく消えたようで、受信アカウントを再度読み取ると、残高は 600 ドルになります。

この状況は、反復不能読み取り (non-repeatable read)と呼ばれ、読み取り偏差とも呼ばれます。つまり、同じデータの 2 回の読み取り結果が矛盾しています。  

2.4 失われたアップデート

2 つのトランザクションが読み取り、変更、書き込みシーケンスを同時に実行し、一方の書き込み操作が他方の書き込み操作の変更をマージせずに、もう一方の書き込み操作の結果を直接上書きするため、データが失われます。この状況は「既知」と呼ばれます。失われたアップデートとして   

更新の消失を回避するより直接的な方法は、一連の読み取り、変更、書き込み操作を使用するのではなく、アトミックな更新を実行することです。カウンターを例にとると、SQL は次のようになります。その原理は通常、読み取られるオブジェクトに対して排他ロックを取得し、同じデータを変更しながらトランザクションが順番に実行されるようにすることです。

update counters set value = value + 1 where key = 1;

読み取り、変更、書き込みの一連の操作を回避できない場合は、明示的にロック (FOR UPDATE) することで更新の損失を回避できます。これにより、同じオブジェクトを読み取ろうとする他のトランザクションは、最初のトランザクションがロックを取得するまでブロックされます。が実行されます。

BEGIN TRANSACTION;

SELECT * FROM xxx FOR UPDATE;

-- 执行业务逻辑
UPDATE xxx SET ...;

COMMIT;

比較および設定 (CAS) は、更新の損失を回避するための比較的一般的な楽観的な操作です。データが更新されると、データ テーブルの値が読み取られた値と比較され、変更がない場合にのみ更新が許可されます。変更がない場合はトランザクションを再試行する必要があります。一般に、CAS はワーク内のデータテーブルにタイムスタンプ列を追加することで実現されます。  

2.5 ファントムの読み取りおよび書き込みの偏差の問題

ファントム読み取りは 1 つの文に要約できます。「1 つのトランザクションの書き込みにより、別のトランザクションの検索クエリの結果が変更されます」。

トランザクション A は、適格なデータを照会し、ビジネス要件を満たしているかどうかをチェックし、チェック結果に基づいてビジネスを継続するかどうかを決定します。この時点でトランザクション B がデータを変更し、トランザクション A のクエリ条件を満たしている場合、トランザクション A が書き込み操作を完了した後、再度クエリを実行すると異なる結果が得られ、書き込みバイアスが発生する可能性があります。 select  select  select   

書き込みスキューの問題は、2 つのトランザクションが同じオブジェクトを読み取り、予期しない例外が発生してそれらの一部を更新する場合に発生します。2 つのトランザクションが 2 つの異なるオブジェクトを更新しているため、これはダーティ書き込みや更新の喪失とは区別されます。以下の例に示すように、アリスとボブの 2 人の医師が当直していますが、二人とも体調が悪いため、休暇をとることにしました。残念ながら、彼らはまったく同時に仕事を終えるボタンを押しました。

ファントムリーディングの例.png

この結果、当直医師がいなくなり、少なくとも 1 人の医師を当直させるという運営上の要件に違反しました。

記述ずれの問題は複数のオブジェクトに関わるため解決が難しく、単一オブジェクトのアトミックな操作方法では解決できません。通常、この問題は分離レベルをシリアル化可能に変更するか、ロックすることで解決されます。

ただし、ロック方法はすべての場合に適用できるわけではありません。例えば、同じ時間帯に複数人が会議室を予約した場合、この時間帯の会議室予約レコードがまだ生成されていないため、複数人で予約レコードを読み込んだ場合、対応する結果値が読み込まれないため、ロックする方法がないため、複数の人が同時に会議室を予約することになります。この状況を解決するには、会議室の期間を管理するデータ テーブルを別に作成し、誰かが一定期間会議室を予約したい場合、その期間のデータをロックし、その後、会議室を予約する必要があります。他のユーザーがクエリに来るとブロックされます。この方法は具体化競合と呼ばれます。 

3. 分離レベル

データベースは常に、トランザクション分離を通じて同時実行性の問題を解決しようとしてきましたシリアル化可能な分離レベルでは、トランザクションがシリアルに実行されることが保証されます。これは、同時実行性の問題が発生しないことを意味します。ただし、実際の運用では、システムのパフォーマンスを確保するために、この分離レベルは使用されないことが多く、より弱い分離レベルが使用されます。場合によっては、データの一貫性は保証されませんが、パフォーマンスを向上させることはできます。システムが良くなります。以下にこれらの分離レベルを紹介します。   

3.1 コミットされていない読み取り

この分離レベルは比較的弱く、ダーティ書き込みのみを回避できます。 

3.2 コミットされた読み取り

この分離レベルは、ダーティ読み取りダーティ書き込みを回避するため、非常に人気があります。   

最も一般的なケースは、ダーティ書き込みを防ぐために行ロックを使用することです。トランザクションが同じオブジェクトを変更したい場合、最初のトランザクションがコミットまたはロールバックして行を続行するためのロックを取得するまで待機する必要があります。  

ダーティ読み取りは読み取りロックを追加することで回避することもできますが、この方法ではデータを読み取るためのロックを保持する長期書き込みトランザクションがある場合に読み取り要求がブロックされるため、この方法は実際には効果的ではありません。これを回避するもう 1 つの方法は、データベースが書き込まれた古い値を記憶していることです。新しい書き込みトランザクションが発生して完了していない場合でも、読み取りリクエストは書き込みトランザクションがコミットされたときにのみ古い値を読み取ります。新しい値を読み取るためです。 。

3.3 反復可能な読み取り

反復可能な読み取りにより 、ダーティ書き込み、ダーティ読み取り、反復不可能な読み取り、および読み取り専用クエリでのファントム読み取りを回避できます。スナップショット分離 は反復可能な読み取りの一般的なソリューションです。各トランザクションは、データベースの一貫したスナップショットから読み取ります。つまり、トランザクションは、トランザクションの開始時にデータベースにコミットされたすべてのデータを参照します。その後、新しいトランザクションによってデータが変更された場合でも、トランザクションはトランザクションの開始時に古いデータを読み取ります。このアプローチは、長時間実行される読み取り専用クエリに非常に役立ちます。クエリ中にデータが絶えず変化する場合、データを分析する方法がないためです。  

スナップショット分離を行わない読み取りコミットでは、データの2 つのバージョンしか記憶されないため、反復可能な読み取りを実現できません。 

スナップショット分離では、書き込みロックも使用してダーティ書き込みを回避し、ダーティ読み取りを回避する方法はロックする必要はありませんが、データベースに保持されているデータ オブジェクトの対応するバージョンを読み取ることによって行われます。その主な原則は、読み取りによって書き込みがブロックされないことです。書き込みは読み取りをブロックしませんこれは、データベースが一貫したスナップショットで長いクエリを処理している間、ロックの競合なしに書き込みを同時に処理できることを意味します。 


InnoDB エンジンを使用した MySQL によるスナップショット分離の実装は、MVCC マルチバージョン同時実行制御であり、単一オブジェクトの複数のバージョンを同時に維持して、異なる時点のノードで複数のデータ状態を提供します。以下でその実装を簡単に見てみましょう。原則です。 

InnoDB エンジン テーブルの場合、クラスター化インデックス レコードには 2 つの必要な非表示列が含まれていますtrx_id  roll_pointer

  • trx_id: トランザクションがクラスター化インデックス レコードを変更するたびに、トランザクションのトランザクション ID が trx_id に割り当てられます。
  • roll_pointer: クラスター化インデックスのレコードが変更されるたびに、古いバージョンがアンドゥ ログに書き込まれます。この隠し列はポインターに相当し、レコードの変更前の情報を見つけることができます。それを理解するために、テーブル hero にレコードが 1 つだけ含まれていると仮定して、例を挙げてみましょう。
mysql> select * from hero;
+-----+-----+
|id   |name |
+-----+-----+
|1    |刘备 |
+-----+-----+

このレコードを挿入するトランザクション ID を 80 に指定します。この時点で、このレコードを変更するために 2 つのトランザクションを開いてください。変更ごとに元に戻すログが生成され、各ログには trx_id 属性と roll_pointer 属性も含まれます。次の図に示すように、roll_pointer 属性を使用して、複数の Undo ログをリンク リストに接続できます。

ロールポインター.png

このリンクされたリストはバージョン チェーンと呼ばれます。バージョン チェーンのヘッド ノードは、現在の最新のレコードです。このレコードのバージョン チェーンを使用して、同じレコードにアクセスするときの同時トランザクションの動作を制御できます。この方法はマルチ チェーンと呼ばれます。バージョン同時実行制御 

トランザクションが最初のクエリを実行すると、一貫性のあるスナップショット (読み取りビュー)が生成されます。これを使用して、バージョン チェーン内のどのバージョンが現在のトランザクションに表示されるかを判断できます。Read View には、さらに次の 4 つの重要なコンテンツが含まれています。 

  • m_ids: 読み取りビューを生成するときに、現在のシステム内のアクティブな読み取りおよび書き込みトランザクションの ID リスト。これらのアクティブなトランザクションがコミットされた場合でも、その書き込みが現在のトランザクションによって無視されることを保証するために使用されます。
  • min_trx_id: 現在のシステムのアクティブな読み取りおよび書き込みトランザクションの最小トランザクション ID
  • max_trx_id: システムが次のトランザクションに割り当てるトランザクション ID
  • Creator_id: 読み取りビューを生成したトランザクションのトランザクション ID

読み取りビューを使用すると、次の手順に従うだけで、レコード内のバージョンが表示されるかどうかを判断できます。

  • アクセスしたバージョンの trx_id 属性値が読み取りビューのクリエイターの Creator_trx_id 値と同じである場合、現在のトランザクションは自身が変更したコンテンツにアクセスしていることを意味し、このバージョンは現在のトランザクションからアクセスできます。
  • アクセスされたバージョンの trx_id 属性値が読み取りビューの min_trx_id 値より小さい場合、このバージョンを生成したトランザクションは現在のトランザクションが読み取りビューを生成する前にコミットされており、これらのバージョンには現在のトランザクションからアクセスできることを示します。
  • アクセスされたバージョンの trx_id 属性が読み取りビューの max_trx_id 値以上である場合、このバージョンを生成するトランザクションは現在のトランザクションが読み取りビューを生成した後に開かれ、現在のトランザクションはこのバージョンにアクセスできないことを示します。
  • アクセスされたバージョンの trx_id 属性の値が読み取りビューの min_trx_id と max_trx_id の間にある場合、trx_id が m_ids リストにあるかどうかを判断する必要があります。存在する場合、読み取りビューの作成時にこのバージョンを生成したトランザクションがまだアクティブであったため、このバージョンは表示されないことを意味します。そうでない場合は、読み取りビューの作成時にこのバージョンを生成したトランザクションを意味しますが送信されており、このバージョンにアクセスできます

つまり、レコードが現在の読み取りトランザクションに表示される場合、レコードを作成する必要があるトランザクションは、現在の読み取りトランザクションが開始される前にコミットされています 

3.4 シリアル化可能

シリアル化可能性は一般に最も強力な分離レベルと考えられており、私たちが訴えているすべてのデータの不整合を回避できます。トランザクションを並行して実行できても、同時実行なしで次々に実行されたかのように最終結果が同じになることを保証できます。つまり、データベースは考えられるすべての競合状態を防ぎます。   

ほとんどのシリアル化可能な実装テクノロジは、トランザクションのシリアル化された実行2 フェーズ ロック 、またはシリアル化可能なスナップショット分離の 3 つの方法のいずれかを採用しています 

トランザクションのシリアル化された実行

このテクノロジの実装では、各トランザクションが小さくて高速である必要があるため、トランザクションの中に遅いトランザクションがあると、当然他のトランザクションも遅くなります。さらに、このアプローチは、アクティブなデータ セットがメモリに収まる場合に限定され、トランザクション内でデータにディスクからアクセスする必要がある場合にもシステムが非常に遅くなります。書き込みスループットは、単一の CPU コアで処理できるほど十分に低くなければなりません。そうでない場合は、トランザクションをパーティション間で調整せずに単一のパーティションに分割する必要があります。もちろん、パーティションをまたがるトランザクションも実装できますが、実行効率は非常に低くなります。したがって、直列化された実行トランザクションのスケーラビリティは劣ります。   

2段ロック(2PL、2相ロック)

2フェーズコミットとは、第1フェーズでトランザクションが実行されるとロック(共有ロック/排他ロック)を取得し、第2フェーズでトランザクションの実行が完了するとロックが解放されます。書き込みがないときに複数のトランザクションが同じオブジェクトを読み取ることができる必要がありますが、書き込みがある限り、排他的アクセスがあり、読み取りブロック書き込み、書き込みブロック読み取りも行われます。これはスナップショット分離とは異なります。ステージをロックすると、シリアル化を達成するための競合状態を回避できます。 

Mysql の InnoDB エンジンは、2PL メカニズムを使用してシリアル化可能な分離レベルを実装します。

2 フェーズ ロックのパフォーマンスが低下するのは、ロックの取得と解放のオーバーヘッドだけでなく、同時実行性の低下も原因です。これは、2 つのトランザクションが同じオブジェクトを変更する場合、2 番目のトランザクションは最初のトランザクションが変更するまで待機する必要があるためです。最後まで実行する。さらに、2PL によって実装されたシリアル化可能な分離でも、頻繁にデッドロックが発生します。

シリアル化可能なスナップショット分離 (SSI、シリアル化可能なスナップショット分離)

シリアル化可能なスナップショット分離は、書き込み間のシリアル化の競合を検出し、どのトランザクションを終了するかを決定するアルゴリズムを追加することにより、スナップショット分離を基盤とするオプティミスティック同時実行制御手法です。  

楽観主義とは、潜在的な危険がある場合にトランザクションをブロックせず、すべてがうまくいくことを期待してトランザクションを実行し続けることを意味します。トランザクションがコミットしようとすると、データベースは何か悪いことが起こったかどうか (つまり、分離が違反されたかどうか) を確認します。もし起こった場合、トランザクションは中止され、再試行する必要があります。競合が高くない場合、オプティミスティック同時実行制御はペシミスティック同時実行制御よりもパフォーマンスが向上する傾向があります。  

トランザクションはデータベースからデータを読み取り、そのデータに基づいて条件判断を行いますが、スナップショット分離の条件下でビジネスロジックを実行する際、クエリ実行後にデータが変更される可能性があるため、前回のクエリ結果が最新でないことがよくあります。そのため、実行されるビジネスロジックが異常である可能性があります。したがって、トランザクションのコミット時に以前に読み取られたデータが変更されたかどうかを判断するには、次の 2 つの検証が必要です。  

  1. 読み取りの前にコミットされていない書き込みをチェックする
  2. 読み取り後に書き込みをチェックする

これらのチェックに合格した後でのみ、トランザクションのコミット時に使用されるデータが新しいことが保証されます。

シリアル実行と比較すると、シリアル化可能なスナップショット分離は単一の CPU コアのスループットに制限されないため、スケーラビリティが優れています。シリアル化可能なスナップショット分離は 2 フェーズ ロックと比較され、その最大の利点はトランザクションをブロックする必要がないことです。スナップショット分離と同様に、別のトランザクションによって保持されているロックを待ちます。読み取りによって書き込みがブロックされず、書き込みによって読み取りがブロックされません。これは、読み取りがより容易なビジネス シナリオに非常に適しています。

シリアル化可能なスナップショット分離のパフォーマンスは中止率に反映されます。長期にわたる読み取りおよび書き込みトランザクションが多数ある場合、競合が頻繁に発生し、トランザクションの中止が発生する可能性があります。したがって、比較的短いトランザクションの場合、シリアル化可能なスナップショット分離のパフォーマンスが向上します。

4. 適時性と完全性

ACID トランザクションは通常、強い整合性を保証します。つまり、書き込み者はトランザクションがコミットされるまで待機し、書き込みが完了すると、書き込みの結果がすべての読み取り者に表示されます。強整合性のセマンティクスでは、特に考慮する価値のある側面が 2 つあります。 

  • 適時性: これは、ユーザーがシステムの最新の状態を確実に観察できるようにすることを意味します。強整合性ではなく結果整合性の場合、ユーザーは古いデータを読み取る可能性がありますが、この不整合は一時的なものであり、待機して再試行するだけで最終的には解決されます。
  • 整合性: 整合性とは、データに損失、不整合、またはエラーがないこと、つまり破損がないことを意味します。特に、特定の派生データセット (キャッシュ、検索インデックスなど) は、基礎となるデータベースとの一貫性を保つ必要があります。ACID トランザクションでは、アトミック性と耐久性が整合性を確保するための重要な原則です

興味深いのは、非同期ストリーム処理システムによって実装された分散トランザクションに基づいて、適時性と整合性を分離でき、トランザクションがコミットされる前に明示的に待機するトランザクションを明示的に構築しない限り、整合性だけを保証し、適時性は保証しないことです。特定のメッセージが到着するコンシューマ。

適時性と整合性についての理解を深めるために、ストリーム処理システムに基づいた分散トランザクションの実装例を見てみましょう。

4.1 ログベースのメッセージキューを使用して整合性を確保する

たとえば、転送を例に挙げると、3 つのパーティションがあります。1 つはリクエスト ID を含み、1 つは受取人のアカウントを含み、もう 1 つは支払者のアカウントを含みます。データベースに対する従来のアプローチでは、このトランザクションの実行に 3 つのパーティションにわたるアトミック コミットが必要な場合、分散トランザクションを調整する必要があるため、スループットが低下する可能性があります。しかし実際には、ログベースのメッセージ キューを使用して実装されたストリーム処理システムは、アトミック コミットを必要とせずに同等のデータ整合性を実現できます実行プロセスの例は次のとおりです。   

  1. クライアントは、アカウント A からアカウント B への転送リクエストに一意のリクエスト ID を提供し、リクエスト ID に従って対応するメッセージ キューに追加し、メッセージを永続化します。
  2. コンシューマはリクエストのログを読み取ります。要求メッセージごとに、支払者の借方指示 (A パーティション)、受取人の貸方指示 (B パーティション) という 2 つのメッセージが出力ストリームに送信され、送信されたメッセージには元の要求 ID が含まれます。
  3. その後の消費者の消費の借方および貸方の指示、ID に基づく重複排除、およびアカウントの残高への変更の適用

複数のパーティション間のデータの整合性を確保し、分散トランザクション (2PC などのプロトコル) の調整を回避するには、まずこのトランザクションによって実行される内容を単一のレコードに永続化してから、このメッセージ レコードからクレジットを取得する必要があります。借方と借方の指示。ほとんどすべてのデータ システムでは、単一オブジェクトの書き込みはアトミックです。リクエストはログに記録されるか記録されません。

ストリーム処理がステップ 2 でクラッシュした場合、最後のアーカイブ ポイントから処理を再開するため、メッセージはスキップされませんが、複数の重複した借方/貸方命令が生成される可能性がありますが、決定的であるため、生成されるのは同じ命令だけです。ステップ 3 のプロセッサは、ID 値によって簡単に重複を排除できます。

上の例では、操作を複数のステージにまたがるストリーム プロセッサに分割しています。メッセージ レコードの消費は非同期です。送信者はメッセージが消費されて処理されるのを待たず、メッセージとメッセージの処理結果が処理されます。デカップリングにより、適時性は保証されませんでしたが、完全性は保証されます。   

一般に、信頼性の高いストリーム処理システムを使用する場合、分散トランザクションを調整したり、他のアトミック コミット プロトコルを採用したりしなくても、整合性を保証できます。

  • 書き込み操作の内容を単一のメッセージとして表し、書き込みのアトミック性を保証します。
  • このメッセージから他の必要な状態変更を導き出す
  • 重複排除の目的を達成し、べき等性を保証するために、クライアントによって生成されたリクエスト ID をすべての処理層に渡します。
  • メッセージが不変であることが保証され、いつでも派生データを再処理できるため、エラーからの回復が容易になります。

4.2 誠実さの重要性

ACID トランザクションであっても、ストリーム処理システムに基づく分散トランザクションであっても、それらはすべてデータの整合性を保証します。適時性の違反は混乱を招く可能性がありますが、それは一時的なものですが、完全性の違反は壊滅的な影響を与える可能性があるためです。一貫性の違反、最終的な一貫性、整合性の違反、決して一貫性がない、が最良の一般化です。


巨人の肩

著者: JD Logistics 王一龍

出典: JD Cloud 開発者コミュニティ

HuaweiがHarmonyOS 4 miniblinkバージョン108を正式リリース、コンパイルに成功 世界最小のChromiumカーネル Vimの父、Bram Moolenaar氏が病気で死去 . ChromeOSはブラウザとオペレーティングシステムを独立した Bilibili(ビリビリ)ステーションに分割し、再び崩壊 . HarmonyOS NEXT: フル使用 自社開発カーネル Nim v2.0 正式リリース、命令型プログラミング言語 Visual Studio Code 1.81 リリース Raspberry Pi 月産能力 100 万台達成 Babitang 初のレトロメカニカルキーボード発売
{{名前}}
{{名前}}

おすすめ

転載: my.oschina.net/u/4090830/blog/10093454