1. 概要:
他の多くのデータベースと同様、NoSQL データベースとしての Redis もトランザクション メカニズムを提供します。 Redis では、MULTI/EXEC/DISCARD/WATCH の 4 つのコマンドがトランザクション実装の基礎となります。この概念は、リレーショナル データベース開発の経験を持つ開発者にとってはなじみのないものではないと思いますが、それでも、Redis でのトランザクションの実装特性を簡単にリストします: (推奨: redis ビデオ チュートリアル )
1 ). トランザクション内のすべてのコマンドはシリアル順序で実行されます。トランザクションの実行中、Redis は他のクライアント リクエストにサービスを提供しなくなるため、トランザクション内のすべてのコマンドがアトミックに実行されます。
2). リレーショナル データベースのトランザクションと比較すると、Redis トランザクションではコマンドの実行が失敗しても、後続のコマンドは引き続き実行されます。
3). MULTI コマンドを通じてトランザクションを開始できますが、これはリレーショナル データベース開発の経験がある人であれば「BEGIN TRANSACTION」ステートメントとして理解できます。このステートメントの後に実行されるコマンドはトランザクション内の操作とみなされ、最後に EXEC/DISCARD コマンドを実行することで、トランザクション内のすべての操作をコミット/ロールバックできます。これら 2 つの Redis コマンドは、リレーショナル データベースの COMMIT/ROLLBACK ステートメントと同等であるとみなすことができます。
4). トランザクションが開始される前に、クライアントとサーバー間の通信障害が発生し、ネットワークが切断された場合、実行される後続のすべてのステートメントはサーバーによって実行されません。ただし、クライアントが EXEC コマンドを実行した後にネットワーク中断イベントが発生した場合、トランザクション内のすべてのコマンドがサーバーによって実行されます。
5).追加専用モードを使用する場合、Redis はシステム関数 write を呼び出すことにより、この呼び出しでトランザクション内のすべての書き込み操作をディスクに書き込みます。ただし、電源障害によるダウンタイムなど、書き込みプロセス中にシステム クラッシュが発生した場合、その時点ではデータの一部だけがディスクに書き込まれ、データの他の部分が失われる可能性があります。
Redis サーバーは、再起動時に必要な一連の整合性チェックを実行します。同様の問題が見つかると、ただちに終了し、対応するエラー プロンプトが表示されます。現時点では、Redis ツールキットで提供されている redis-check-aof ツールを最大限に活用する必要があります。このツールは、データの不整合エラーを特定し、書き込まれたデータの一部をロールバックするのに役立ちます。修復後、Redis サーバーを再度再起動できます。
2. 関連コマンドのリスト:
コマンド プロトタイプ |
時間計算量 |
コマンドの説明 |
戻り値 |
M
U
L
T
I
|
|
はトランザクションの開始をマークするために使用されます。それ以降に実行されるコマンドはすべてコマンド キューに保存されます。これらのコマンドは、EXEC が実行されるまでアトミックには実行されません。 |
常に OK |
E
XX
E
C
| ## を返します
| #コマンド キュー内のすべてのコマンドをトランザクション内で実行し、同時に現在の接続の状態を通常の状態、つまり非トランザクション状態に戻します。トランザクション中に WATCH コマンドが実行される場合、EXEC コマンドは、WATCH によって監視されているキーが変更されていない場合にのみ、トランザクション キュー内のすべてのコマンドを実行できます。それ以外の場合、EXEC は現在のトランザクション内のすべてのコマンドを破棄します。 | トランザクション内の各コマンドの結果をアトミックに返します。トランザクションで WATCH が使用されている場合、トランザクションが放棄されると、EXEC は NULL-multi-bulk 応答を返します。 |
##D
I
S
C
A
R D
|
|
トランザクション キュー内のすべてのコマンドをロールバックし、同時に現在の接続のステータスを通常の状態、つまり非トランザクション状態に戻します。 WATCH コマンドを使用すると、このコマンドはすべてのキーの監視を解除します。 |
常に OK を返します。 |
#WATCHkey [key ...]
| O(1) | MULTI コマンドを実行する前に、監視するキーを指定できますが、EXEC を実行する前に監視対象のキーが変更された場合、EXEC はトランザクション キュー内のすべてのコマンドの実行を中止します。 | 常に OK を返します。 |
#U
N
W
A
T
C
H
O(1) |
現在のトランザクションで指定された監視対象キーをキャンセルします。EXEC または DISCARD コマンドが実行される場合、手動で行う必要はありません。この後、トランザクション内のすべての監視対象キーが自動的にキャンセルされるため、コマンドを実行します。 |
常に OK を返します。 |
|
3. コマンドの例:
1. トランザクションは通常どおり実行されます:
#シェル コマンド ラインで Redis クライアント ツールを実行します。
#
#現在の接続で新しいトランザクションを開始します。 #
redis 127.0.0.1:6379> multi
OK
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
#トランザクションの最初のコマンドを実行します。コマンドの戻り結果から、コマンドはすぐには実行されず、トランザクションのコマンド キューに格納されていることがわかります。 #redis 127.0.0.1:6379> incr t1
QUEUED
ログイン後にコピー
#新しいコマンドが実行され、その結果から、トランザクションのコマンドキューにもコマンドが格納されていることがわかります。
#
redis 127.0.0.1:6379> incr t2
QUEUED
ログイン後にコピー
#トランザクションコマンドキュー内のコマンドをすべて実行すると、結果からわかるように、キュー内のコマンドの結果が返されます。
redis 127.0.0.1:6379> exec
1) (integer) 1
2) (integer) 1
ログイン後にコピー
2.トランザクションに失敗したコマンドがあります: #新しいトランザクションを開始します。
#
redis 127.0.0.1:6379> multi
OK
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
#キー a の値を文字列型の 3 に設定します。 #
redis 127.0.0.1:6379> set a 3
QUEUED
ログイン後にコピー
# キーaに関連付けられた値の先頭から要素をポップします 値は文字列型であり、lpopコマンドはリスト型にしか使用できないため、execコマンド実行時に、コマンドは失敗します。
#redis 127.0.0.1:6379> lpop a
QUEUED
ログイン後にコピー
#キー a の値を文字列 4 に再度設定します。 #
redis 127.0.0.1:6379> set a 4
QUEUED
ログイン後にコピー
#キー a の値を取得して、トランザクションの 2 番目の set コマンドで値が正常に設定されたかどうかを確認します。 #redis 127.0.0.1:6379> get a
QUEUED
ログイン後にコピー
#結果から、トランザクション内の 2 番目のコマンド lpop は実行に失敗しましたが、後続の set コマンドと get コマンドは正常に実行されたことがわかります。これは、Redis のトランザクションおよびリレーショナル タイプです。 . データベース内のトランザクション間の最も重要な違い。
redis 127.0.0.1:6379> exec
1) OK2) (エラー) ERR 間違った種類の値を保持するキーに対する操作です
3) OK
4) "4" 3. ロールバック トランザクション:
#トランザクションが実行される前にキー t2 の値を設定します。
#redis 127.0.0.1:6379> set t2 tt
OK
ログイン後にコピー
#トランザクションを開きます。
#
redis 127.0.0.1:6379> multi
OK
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
# トランザクション内でこのキーに新しい値を設定します。
#redis 127.0.0.1:6379> set t2 ttnew
QUEUED
ログイン後にコピー
#取引を中止します。
#redis 127.0.0.1:6379> discard
OK
ログイン後にコピー
#キー t2 の値を表示します。結果から、このキーの値はトランザクションが開始される前の値のままであることがわかります。
redis 127.0.0.1:6379> get t2
"tt"
ログイン後にコピー
4. WATCH コマンドと CAS ベースのオプティミスティック ロック:
Redis トランザクションでは、WATCH コマンドを使用して CAS ( check -and-set) 関数。トランザクションが実行される前に WATCH コマンドを通じて複数の Key を監視すると仮定します。WATCH 後にいずれかの Key の値が変更された場合、EXEC コマンドによって実行されたトランザクションは放棄され、呼び出し元に通知するために Null マルチバルク応答が返されます。トランザクションの実行に失敗しました。
たとえば、Redis にはキー値のアトミックなインクリメントを完了するための incr コマンドが提供されていないと仮定します。この関数を実装したい場合は、対応するコードを自分で記述するしかありません。疑似コードは次のとおりです。
val = GET mykey
val = val + 1
SET mykey $val
ログイン後にコピー
上記のコードは、このコードを同時に実行する複数のクライアントがあるため、単一接続の場合にのみ実行結果が正しいことを保証できます。 , 次に、マルチスレッド プログラムでよく発生するエラー シナリオ、つまり競合状態が発生します。
たとえば、クライアント A と B は両方とも mykey の元の値を同時に読み取ります。値が 10 であるとします。その後、両方のクライアントが値に 1 を追加して、Redis サーバーに設定し直します。これにより、mykey の結果は、私たちが考えているような 12 ではなく、11 になります。同様の問題を解決するには、WATCH コマンドの助けが必要です。次のコードを参照してください。 WATCH mykey
val = GET mykey
val = val + 1
MULTI
SET mykey $val
EXEC
ログイン後にコピー
前のコードとの違いは、新しいコードは WATCH を通じて mykey の値を監視することです。これにより、各接続で EXEC を実行する前に、現在の接続で取得した mykey の値が他の接続されているクライアントによって変更された場合に、EXEC コマンドが有効であることを効果的に確認できます。現在の接続の接続が実行されます。失敗します。このようにして、呼び出し元は戻り値を判断して、val が正常にリセットされたかどうかを知ることができます。
redis についてさらに詳しく知りたい場合は、
redis チュートリアル 列に注目してください。
以上がRedis トランザクションと関連コマンドの概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。