#ACID 属性の説明
Atomicity
内のすべての操作トランザクションはデータベース内で分離できず、すべてが完了するか、何も実行されません。
一貫性
トランザクションを実行すると、データがある状態から別の状態に変換されます。トランザクションの開始前と終了後は、データベースの整合性制約に違反しません。
分離
トランザクションを分離するには、各読み取り/書き込みトランザクションのオブジェクトが他のトランザクションの操作オブジェクトから分離されている必要があります。つまり、トランザクションは他のトランザクションから認識される前には認識されません。それは提出されます。
耐久性
データベースがトランザクションを実行した後、データの変更は永続化される必要があります。データベースを再起動するとき、データの値は変更された値である必要があります。
Redis によるトランザクションの実装方法
実装原理
Redis トランザクションの実行には、次の 3 つのステップが含まれます。
- 顧客end は MULTI コマンドを使用してトランザクションを明示的に開始します。
- サーバーは、クライアントから送信された特定の操作 (データの追加、削除、変更など) を受信し、トランザクション内で実行します。これらの操作は、Redis 自体によって提供されるデータの読み取りおよび書き込みコマンドです。これらのコマンドはクライアントによってサーバーに送信されますが、Redis インスタンスはこれらのコマンドをコマンド キューに一時的に保存するだけで、すぐには実行しません。
- EXEC コマンドが受信されて実行された場合にのみ、Redis はトランザクションをコミットし、トランザクション キュー内のすべてのコマンドを実際に実行します。
トランザクション関連コマンド
- MULTI: トランザクションを開く
- EXEC: トランザクションを送信してコマンドを実行キュー内のすべての操作コマンド。
- DISCARD: トランザクションを破棄してコマンド キューをクリアしますが、トランザクションのロールバックはサポートされません。
- 監視: トランザクションの実行中に 1 つ以上のキーの値が変化するかどうかを検出します。変化した場合、現在のトランザクションは実行を中止します。
Redis トランザクションは ACID をどのようにサポートしますか?
Redis トランザクションはアトミック性をサポートしますか?
- シナリオ 1: トランザクションがエンキューされたときにトランザクションを実行するとエラーが報告され、Redis はトランザクションのアトミック性を確保するためにトランザクションの実行を中止します。
- シナリオ 2: コマンドがキューに入力されたときはエラーが報告されませんが、実際に実行されるとエラーが報告されます。トランザクションのアトミック性は保証できません。
ケース 1 の説明例
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set t1 v1
QUEUED
127.0.0.1:6379> set t2 v2
QUEUED
127.0.0.1:6379> setget t3
(error) ERR unknown command 'setget'
127.0.0.1:6379> set t4 v4
QUEUED
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get t4
(nil)
ログイン後にコピー
説明: exec コマンドを実行する前に、構文エラーが発生した場合 (存在しないコマンドが使用された場合)、コマンドがキューに入れられると、Redis はエラーを報告し、そのエラーを記録します。Exec コマンドが実行されると、Redi は送信されたすべてのコマンドを拒否し、トランザクションの実行は失敗します。この場合、Reid のトランザクションはアトミック性をサポートできます。
ケース 2 の説明例
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incr s2
QUEUED
127.0.0.1:6379> set a1 v1
QUEUED
127.0.0.1:6379> set a2 v2
QUEUED
127.0.0.1:6379> exec
1) (error) ERR value is not an integer or out of range
2) OK
3) OK
127.0.0.1:6379> get a2
"v2"
ログイン後にコピー
説明: s2 の値は v2 であり、incr コマンドを実行するとエラーが報告されます。これは、incr は整数型の値しか追加できないためですが、この例では私たちが発見したケース Redis トランザクションはロールバックされず、後続のコマンドは正常に実行できるため、このケースではトランザクションのアトミック性は保証できません。
Redis トランザクションは一貫性をサポートしていますか?
シナリオ 1: コマンドがキューに追加されるときにエラーが報告される
最初のケースでは、トランザクション自体が破棄されるため、トランザクションの一貫性が保証されます。
ケース 2: コマンドがキューに追加されたときにエラーは報告されませんが、実際に実行されるときにエラーが報告されます。
2 番目のケースでは、誤ったコマンドは実行されません。ただし、正しいコマンドは正常に実行でき、コマンドの実行時にエラーは報告されません。データベースの一貫性が変化します。
シナリオ 3: Redis インスタンスの実行コマンドの実行が失敗する
- Redis 永続化が RDB に設定されている場合、トランザクションの実行時に生成された RDB スナップショットは実行されないため、トランザクション コマンド操作の結果は RDB スナップショットには保存されませんが、RDB スナップショットを使用してリカバリする場合、データベース内のデータは整合性が保たれます。
- Reids 永続性が AOF に設定されており、トランザクション操作が AOF ログに記録される前にインスタンスが失敗した場合、AOF ログを使用して復元されたデータベース データは一貫しています。 AOF ログに一部の操作のみが記録されている場合は、redis-check-aof を使用してトランザクション内の完了した操作をクリアでき、回復後のデータベースの整合性が保たれます。
Redis トランザクションは分離をサポートしていますか?
Redis トランザクション分離を実現するには、watch コマンドを使用する必要があります。 Watch の原理は、トランザクションの実行前に 1 つ以上のキーの変更を監視する場合、トランザクションが実行する EXEC コマンドを呼び出すときに、WATCH メカニズムが最初に監視対象のキーが他のクライアントによって変更されているかどうかを確認することです。リスナーの値が変更された場合、トランザクションの分離が破壊されるのを防ぐために、トランザクションの実行は放棄されます。
例の説明
クライアント 1:
127.0.0.1:6379> get blance
"100"
127.0.0.1:6379> watch blance
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby blance 10
QUEUED
127.0.0.1:6379> incrby blance 10
QUEUED
127.0.0.1:6379> exec
(nil)
ログイン後にコピー
クライアント 2:
127.0.0.1:6379> get blance
"100"
127.0.0.1:6379> set blance 90
OK
127.0.0.1:6379> get blance
"90"
ログイン後にコピー
説明: クライアント 1 は、監視を使用して残高を検出し、トランザクションを開いた後、実行します。クライアント 2 で残高の値を変更する操作を実行し、トランザクション実行中にウォッチによって監視されるデータを変更する他のクライアントをシミュレートしてから、クライアント 1 の EXEC コマンドを実行すると、トランザクションが正常に実行されなかったことを確認します。
Redis トランザクションは永続性をサポートしていますか?
Redis トランザクションは永続性をサポートできません。Redis が RDB モードを使用している場合、トランザクションの実行後、次の RDB スナップショットが実行される前に、Redis インスタンスがクラッシュします。この場合、トランザクションの変更されたデータが維持されることは保証できません。 Redis が AOF モードを採用している場合、永続化設定が no、everysec、always のいずれであってもデータ損失が発生する可能性があるため、Redis がどの永続化モードを採用してもトランザクションの耐久性に影響を与えるため、サポートできません。
以上がRedis トランザクションを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。