redis multi コマンド


redis multi コマンド

参考

MULTI, EXEC, DISCARD および WATCH は Redis におけるトランザクションの基本です。これらは、複数のコマンドの実行をひとつのステップで行えるようにします。その際、2 つの重要な点が保証されます。

トランザクション中のすべてのコマンドは直列化され、順に実行されます。他のクライアントにより発行されたリクエストが、Redis トランザクションの 途中に 入り込むことはありません。このことは、コマンド群がひとつの隔離されたオペレーションとして実行されることを保証します。

すべてのコマンドが実行されるか、ひとつも実行されないかのいずれかであり、すなわち Redis のトランザクションはアトミックです。 EXEC コマンドはトランザクション中の全コマンドの実行のトリガです。もし、クライアントがトランザクションの途中で、 MULTI [訳注: EXEC の間違い?] コマンド実行前にサーバーとの接続を失うと、いずれのオペレーションも実行されません。その反対に、 EXEC コマンドが呼び出されると、すべてのオペレーションが実行されます。もし append only file を使用している場合、Redis はトランザクションの内容をディスクに書き込むために、ひとつの write(2) システムコールを呼び出します。しかしながら、Redis サーバーがクラッシュ、または管理者により困難な方法で kill された場合に、一部のオペレーションのみが記入されてしまうことはあり得ます。Redis は再起動時にこの状態を検知し、エラーを発生させて終了します。 ‘redis-check-aof’ ツールを使って修復することで、サーバーを起動できるようになります。

実験1 (exec コマンド成功)

①. Aマシンで redis-cli を使用する
②. Bマシンで redis-cli を使用する
③. Aマシンで get を実行

sample-redis-001.mylolu.0001.usw2.cache.amazonaws.com:6379> get sample-key-0001
(nil)

④. Bマシンで multi コマンド~exec コマンド手前まで実行

sample-redis-001.mylolu.0001.usw2.cache.amazonaws.com:6379> multi
OK
sample-redis-001.mylolu.0001.usw2.cache.amazonaws.com:6379> set sample-key-0001 "aaaaaa"
QUEUED
sample-redis-001.mylolu.0001.usw2.cache.amazonaws.com:6379> set sample-key-0002 "bbbbbb"
QUEUED
sample-redis-001.mylolu.0001.usw2.cache.amazonaws.com:6379>

⑤. Aマシンで get を再度実行

sample-redis-001.mylolu.0001.usw2.cache.amazonaws.com:6379> get sample-key-0001
(nil)

⑥. Bマシンで exec を実行

sample-redis-001.mylolu.0001.usw2.cache.amazonaws.com:6379> exec
1) OK
2) OK

⑦. Aマシンで get を実行

sample-redis-001.mylolu.0001.usw2.cache.amazonaws.com:6379> get sample-key-0001
"aaaaaa"
sample-redis-001.mylolu.0001.usw2.cache.amazonaws.com:6379> get sample-key-0002
"bbbbbb"

実験2 (exec コマンド失敗)

EXEC が呼び出された 後に コマンドが失敗することもあります。たとえば、誤った値をもったキーに対する操作を行った場合(文字列値に対して、リスト操作を実行する、というように)などです。

Redis 2.6.5 以降、サーバーはコマンドの累積中にエラーが発生したことを覚えておき、 EXEC コール時にトランザクションの実行を拒否するとともにエラーを返し、トランザクションを自動的に破棄するようになりました。

EXEC コマンドの後に起こるエラーには、特別なハンドリングは行われません: トランザクション中にいくつかのコマンドが失敗したとしても、その他のすべてのコマンドはそのまま実行されます。

(Redis 3.2.10 で確認)

① exec コマンド実行時に、一部のコマンドでエラーを発生させてみる

sample-redis-001.mylolu.0001.usw2.cache.amazonaws.com:6379> multi
OK
sample-redis-001.mylolu.0001.usw2.cache.amazonaws.com:6379> set sample-exec-error-key "cccc"
QUEUED
sample-redis-001.mylolu.0001.usw2.cache.amazonaws.com:6379> lpop sample-exec-error-key
QUEUED
sample-redis-001.mylolu.0001.usw2.cache.amazonaws.com:6379> exec
1) OK
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value

② 「①」で成功したコマンドの結果を取得してみる

sample-redis-001.mylolu.0001.usw2.cache.amazonaws.com:6379> get sample-exec-error-key
"cccc"

⇒ Multi コマンドにて、成功したコマンドはロールバックしない