Redis Transaction

スポンサーリンク

Redisのトランザクションについてまとめます。MULTIコマンドを使用するとアトミックな(原子性のある)制御をし、WATCHコマンドを使用すると楽観的排他制御を実現できます。

前提

公式ドキュメント

参考になる公式ドキュメントを以下に示します。

動作確認済環境

  • Rocky Linux 8.6
  • Redis 5.0.3

MULTIコマンド

COMMIT処理(EXECコマンド)

MULTIコマンドを使用すると、一連のコマンドをアトミックに処理できます。まずはテスト用のデータを投入します。

127.0.0.1:6379> SET foo 1
OK
127.0.0.1:6379> SET baa 1
OK
127.0.0.1:6379>

MULTIコマンド入力後の処理が1つのトランザクションとして扱われます。以下の操作例の場合は、fooとbaaの加算が1つのトランザクションとして実行されます。

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> INCR foo
QUEUED
127.0.0.1:6379> INCR baa
QUEUED
127.0.0.1:6379> 

トランザクションを処理(実行)する場合は、EXECコマンドを実行します。RDBMSにおけるCOMMIT相当の操作です。

127.0.0.1:6379> EXEC
1) (integer) 2
2) (integer) 2
127.0.0.1:6379> 

ROLLBACK処理(DISCARDコマンド)

MULTIコマンドをの過程で、DISCARDコマンドを使用するとトランザクションを破棄します。まずはテスト用のトランザクションを作成します。

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> INCR foo
QUEUED
127.0.0.1:6379> INCR baa
QUEUED
127.0.0.1:6379> 

DISCARDコマンドを使用すると、トランザクションを破棄できます。

127.0.0.1:6379> DISCARD
OK
127.0.0.1:6379> 

WATCHコマンド(楽観的排他制御)

処理成功の場合

WATCHコマンドを使うと、楽観的排他制御ができます。以下のようにWATCHコマンドを使用すると、他者がfooの値を変更していない場合のみ処理が成功します。

127.0.0.1:6379> SET foo 1
OK
127.0.0.1:6379> WATCH foo
OK
127.0.0.1:6379> 

以下のようにMULTIコマンドとEXECコマンドを使用すると、WATCHコマンド実行からEXECコマンドまでの間で他者がfooの値を変更していない場合のみ処理が成功します。

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> INCR foo
QUEUED
127.0.0.1:6379> EXEC
1) (integer) 2
127.0.0.1:6379> 

処理失敗の場合

処理失敗の場合も観察してみましょう。まず、ある端末でWATCHコマンドを実行します。

127.0.0.1:6379> SET foo 1
OK
127.0.0.1:6379> WATCH foo
OK
127.0.0.1:6379> 

その後、別の端末でfooの値を変更します。

127.0.0.1:6379> SET foo 5
OK
127.0.0.1:6379> 

楽観的排他制御 01

この状態でfooの値の変更を試みると、EXECコマンド実行時にnilが返されます。

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> INCR foo
QUEUED
127.0.0.1:6379> EXEC
(nil)
127.0.0.1:6379> 

楽観的排他制御 02

タイトルとURLをコピーしました