ホームページ >データベース >Redis >Redis ピット防止ガイド - トランザクション

Redis ピット防止ガイド - トランザクション

王林
王林転載
2021-01-27 09:14:062200ブラウズ

Redis ピット防止ガイド - トランザクション

関連コマンドの紹介:

(学習ビデオ共有: redis ビデオ チュートリアル)

Redis ピット防止ガイド - トランザクション

注:

------MULTI、EXEC、DISCARD は、トランザクションを明示的に開始および制御するための一般的なコマンドであり、リレーショナル データベースの BEGAIN、COMMIT、ROLLBACK と比較できます (実際には、ギャップ非常に大きい);

------WATCH コマンドの使用は、トランザクションの同時実行によって引き起こされる反復不可能な読み取りとファントム読み取りの問題を解決することです (単純にキーのロックとして理解されます);

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

上記のコマンド実行からわかるように、EXEC は配列を返します。この配列の各要素はトランザクション内の 1 つのコマンドの戻り結果であり、その順序は、コマンドが発行されました。 Redis 接続が MULTI リクエストのコンテキストにある場合、すべてのコマンドは文字列 QUEUED で応答され (Redis プロトコルの観点からステータス応答として送信されます)、コマンド キューに入れられます。 EXEC が呼び出された場合にのみ、キューに入れられたコマンドが実行され、この時点で実際の結果が返されます。

トランザクションのエラー

トランザクション中に、次の 2 種類のコマンド エラーが発生する可能性があります。

EXEC コマンドを呼び出す前にエラーが発生しました (COMMAND キューイングが失敗しました)。たとえば、コマンドに構文エラー (パラメーターの数が間違っている、コマンド名が間違っているなど) がある場合や、メモリー不足 (サーバーに maxmemory ディレクティブを使用してメモリー制限がある場合) など、特定の重大な状態が存在する場合があります。

クライアントは、EXEC を呼び出す前に最初のエラーを検出します。キューに入れられたコマンドのステータス応答をチェックして (***注: これは実行結果ではなく、キューに入れられたステータス応答を指します***)、コマンドが QUEUED で応答する場合、コマンドは正しくキューに入れられています。それ以外の場合、Redis はエラー。コマンドのキューイング中にエラーが発生した場合、ほとんどのクライアントはトランザクションを中止し、コマンド キューをクリアします。ただし:

Redis 2.6.5 より前では、この場合、EXEC コマンドが呼び出された後、クライアントはコマンドのサブセット (正常にキューに入れられたもの) を実行し、以前のエラーを無視していました。 Redis 2.6.5 以降、サーバーはコマンドの蓄積中に発生したエラーを記憶し、EXEC コマンドが呼び出されると、トランザクションの実行を拒否してこれらのエラーを返し、コマンド キューを自動的にクリアします。例は次のとおりです。

>MULTI
+OK
>INCR a b c
-ERR wrong number of arguments for 'incr' command

これは INCR コマンドの構文エラーが原因であり、EXEC を呼び出してトランザクションを終了する前に検出されます (バージョン 2.6.5)。

EXEC コマンドの呼び出し後にエラーが発生しました。たとえば、不正な値を使用してキーに対して操作を実行する (文字列値に対してリスト操作を呼び出すなど)

EXEC コマンドの実行後に発生するエラーは、特別に処理されません。トランザクション内のコマンドは実行に失敗しますが、他のコマンドは引き続き正常に実行されます。

例は次のとおりです。

>MULTI
+OK
>SET a 3
+QUEUED
>LPOP a
+QUEUED
>EXEC
*2
+OK
-ERR Operation against a key holding the wrong kind of value

EXEC は 2 つの要素を含む文字列配列を返します。1 つの要素は OK、もう 1 つは -ERR..​​. です。エラーがユーザーに適切にフィードバックされるかどうかは、クライアント ライブラリ (Spring-data-redis.redisTemplate など) の実装に依存します。コマンドが失敗した場合でも、キュー内の他のすべてのコマンドが処理されることに注意してください。Redis はコマンドの処理を停止しません。

Redis トランザクションはロールバックをサポートしていません (強調)

実際、Redis コマンドはトランザクションの実行中に失敗する可能性がありますが、残りのコマンドはロールバック (トランザクション ロールバック) の代わりに実行され続けます。リレーショナル データベースを使用したことがある場合は、この状況が奇妙に見えるかもしれません。ただし、この状況には適切な説明があります:

Redis命令可能会执行失败,仅仅是由于错误的语法被调用(命令排队时检测不出来的错误),或者使用错误的数据类型操作某个Key: 这意味着,实际上失败的命令都是编程错误造成的,都是开发中能够被检测出来的,生产环境中不应该存在。(这番话,彻底甩锅,“都是你们自己编程错误,与我们无关”。)由于不必支持Rollback,Redis内部简洁并且更加高效。

“如果错误就是发生了呢?”这是一个反对Redis观点的争论。然而应该指出的是,通常情况下,回滚并不能挽救编程错误。鉴于没有人能够挽救程序员的错误,并且Redis命令失败所需的错误类型不太可能进入生产环境,所以我们选择了不支持错误回滚(Rollback)这种更简单快捷的方法。

清除命令队列

DISCARD被用来中止事务。事务中的所有命令将不会被执行,连接将恢复正常状态。

> SET foo 1
OK
> MULTI
OK
> INCR foo
QUEUED
> DISCARD
OK
> GET foo
"1"

相关推荐:redis数据库教程

以上がRedis ピット防止ガイド - トランザクションの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.imで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。