の キーを解放しても常に OK です。 <blockquote>
<p><em><strong>注:</strong></em></p>
<p>------<code>MULTI ,EXEC ,DISCARD は、トランザクションを開いて制御するための explicit 一般的なコマンドであり、リレーショナル データベース の BEGAIN ,COMMIT## と比較できます。 #, ROLLBACK (実際には、ギャップは非常に大きい); ------WATCH コマンドは、 トランザクションの同時実行性を解決するために使用されます 結果として生じる non-repeatable read および phantom read の問題 (単純に Key をロックすると理解されます);
# RedisTransaction
MULTI、EXEC、DISCARD、WATCH は Redis トランザクションの基礎です。 は、トランザクションを明示的に開始および制御するために使用され、一連のコマンドを 1 つのステップ で実行できるようにします。また、次の 2 つの重要な保証が提供されます。
トランザクション内のすべてのコマンドはシリアル化され、順番に実行されます。 Redis トランザクションの実行中、別のクライアントによって発行されたリクエストは発生しません。これにより、コマンド キュー- が単一のアトミック操作として実行されることが保証されます。
キュー内のコマンドはすべて処理されるか、無視されます。 EXEC コマンドは、トランザクション内のすべてのコマンドの実行をトリガーするため、トランザクションのコンテキストでクライアントがサーバーへの接続を失った場合、MULTI コマンドが呼び出される前に発生した場合、 コマンドは実行されません。 - が実行されます。 ;
- これより前に EXEC コマンドが呼び出された場合、すべての
コマンド が実行されます。
-
同時に、redis は AOF ( 追加専用ファイル ) を使用し、追加の 書き込み操作 を使用してトランザクションをディスクに書き込みます。ダウンタイムやプロセスのクラッシュなどが発生した場合は、redis-check-aof ツールを使用して追加専用ファイルを修復すると、サービスが正常に起動して一部の操作を再開できるようになります。 使用法
MULTI コマンド を使用して、Redis トランザクションを明示的に開きます。このコマンドは常に OK で応答します。 現時点では、ユーザーは複数のコマンドを発行できますが、Redis はこれらのコマンドを実行せず、キューに入れます 。 EXEC 呼び出されると、すべてのコマンドが実行されます。 DISCARD を呼び出すと、 トランザクションの コマンド キュー をクリアし、 トランザクション を終了できます。 次の例では、キー foo と bar をアトミックにインクリメントします。
>MULTI
OK
>INCR foo
QUEUED
>INCR bar
QUEUED
>EXEC
1)(整数)1
2)(整数)1 上記のコマンド実行からわかるように、 を返します。ここで、各要素はトランザクション内の 1 つのコマンドです。返される結果は、コマンドが発行された順序と同じ順序になります。
Redis 接続が MULTI リクエストのコンテキストにある場合、すべてのコマンドは 文字列 QUEUED で応答されます ( は Redis プロトコルの観点からステータス応答として送信されます) )、コマンド キュー にキューに入れられます。 EXEC が呼び出された場合にのみ、キューに入れられたコマンドが実行され、実際の結果が返されます 。 トランザクションのエラー トランザクション中に、次の 2 つのコマンド エラーが発生する可能性があります。
エラーが発生しました。 EXEC コマンドを呼び出す前に発生しました ( COMMAND がキューに失敗しました)。 -
たとえば、コマンドに 構文エラーがある可能性があります (パラメータの数が間違っている、コマンド名が間違っている...); または メモリ不足などの主要な条件 - (サーバーに
maxmemory ディレクティブを使用した メモリ制限がある場合)。 -
クライアントは、 EXEC を呼び出す前に最初のエラー を検出します。キューに入れられたコマンドの ステータスを確認して を返信します (***注: これは、 実行結果ではなく、キューに入れられた の ステータス応答 を指します) * **)、コマンドが QUEUED で応答した場合、コマンドは正しくキューに入れられます。それ以外の場合、Redis はエラーを返します。コマンドのキューイング中にエラーが発生した場合、ほとんどのクライアントは トランザクションを中止し、コマンド キューをクリアします 。ただし:
Redis 2.6.5 より前の場合、この場合、 EXEC コマンドが呼び出された後、クライアントはコマンドのサブセット (コマンドを正常にキューに入れました)、以前のエラーは無視されます。 Redis 2.6.5
EXEC コマンドの呼び出し後にエラーが発生しました。
たとえば、 間違った値 を使用して key に対して操作を実行する (- String# で List# を呼び出すなど) ## value ##Operation)
- EXEC
コマンド実行後に発生したエラーは特別に扱われません :たとえ一部のコマンドがトランザクションが実行されます。失敗しても、他のコマンドは通常どおり実行されます 。 <ul><li>示例如下:</li></ul><pre class="brush:js;toolbar:false;">>MULTI
+OK
>SET a 3
+QUEUED
>LPOP a
+QUEUED
>EXEC
*2
+OK
-ERR Operation against a key holding the wrong kind of value</pre><blockquote><ul>
<li>
<code>EXEC 返回一个包含两个元素的字符串数组,一个元素是OK ,另一个是-ERR…… 。
- 能否将错误合理的反馈给用户这取决于
客户端library (如:Spring-data-redis.redisTemplate )的自身实现。
- 需要注意的是,即使命令失败,队列中的所有其他命令也会被处理----Redis不会停止命令的处理。
Redis事务不支持Rollback(重点 )
事实上Redis命令 在事务执行时可能会失败,但仍会继续执行剩余命令 而不是Rollback (事务回滚)。如果你使用过关系数据库 ,这种情况可能会让你感到很奇怪。然而针对这种情况具备很好的解释:
-
Redis命令 可能会执行失败,仅仅是由于错误的语法被调用(命令排队时检测不出来的错误),或者使用错误的数据类型操作某个Key : 这意味着,实际上失败的命令都是编程错误造成的,都是开发中能够被检测出来的,生产环境中不应该存在。(这番话,彻底甩锅,“都是你们自己编程错误,与我们无关”。)
- 由于不必支持
Rollback ,Redis 内部简洁并且更加高效。
“如果错误就是发生了呢?”这是一个反对Redis 观点的争论 。然而应该指出的是,通常情况下,回滚并不能挽救编程错误。鉴于没有人能够挽救程序员的错误,并且Redis命令 失败所需的错误类型不太可能进入生产环境,所以我们选择了不支持错误回滚(Rollback)这种更简单快捷的方法。
清除命令队列
DISCARD 被用来中止事务。事务中的所有命令将不会被执行,连接将恢复正常状态。
> SET foo 1
OK
> MULTI
OK
> INCR foo
QUEUED
> DISCARD
OK
> GET foo
"1" 更多编程相关知识,请访问:编程视频!!
|