Redis Transactions

Redisのトランザクションを使用すると、複数のコマンドを単一のユニットとして実行できます。このレッスンでは、トランザクションの使用方法と注意点について解説します。

トランザクションとは

トランザクションは、他のコマンドに中断されることなく順次実行されるコマンドの集合です。

MULTI → コマンド1 → コマンド2 → コマンド3 → EXEC

基本コマンド

MULTI:トランザクションの開始

REDIS
MULTI
OK

EXEC:トランザクションの実行

REDIS
MULTI
OK

SET name "Alice"
QUEUED

SET age 25
QUEUED

EXEC
1) OK
2) OK

DISCARD:トランザクションのキャンセル

REDIS
MULTI
OK

SET name "Bob"
QUEUED

DISCARD
OK

トランザクションのプロパティ

コマンドキュー

トランザクション内のコマンドはすぐに実行されず、キューに入れられます:

REDIS
MULTI
OK

SET a 1
QUEUED

SET b 2
QUEUED

GET a
QUEUED

EXEC
1) OK
2) OK
3) "1"

アトミック性

トランザクション内のコマンドは、すべて実行されるか、まったく実行されないかのどちらかです:

REDIS
MULTI
OK

SET a 1
QUEUED

SET b 2
QUEUED

EXEC
1) OK
2) OK
⚠️ 補足: Redisのトランザクションはロールバックをサポートしていません。トランザクション内でコマンドが失敗しても、他のコマンドは実行されます。

WATCH:楽観的ロック

WATCHはキーを監視します。監視されたキーがトランザクション実行前に変更された場合、トランザクションはキャンセルされます。

基本的な使用方法

REDIS
# キーを監視
WATCH mykey
OK

# トランザクションを開始
MULTI
OK

# キーを変更
SET mykey "new_value"
QUEUED

# トランザクションを実行
EXEC
(nil)  # トランザクションがキャンセルされた場合(キーが変更された場合)はnilを返す

楽観的ロックの実装

例:楽観的ロック

BASH
# クライアント1
WATCH balance
GET balance
MULTI
SET balance 900
EXEC

# クライアント2(クライアント1がEXECを実行する前)
SET balance 800
▶ 試してみよう

ユースケース

1. 在庫の引き落とし

例:在庫を減らす

BASH
# 在庫を減らす(アトミック操作)
MULTI
DECR stock:product:123
INCR sold:product:123
EXEC
▶ 試してみよう

2. 送金

例:送金

BASH
# 送金:ユーザーAからユーザーBに100を送る
MULTI
DECRBY balance:user:a 100
INCRBY balance:user:b 100
EXEC
▶ 試してみよう

3. バッチ操作

例:バッチ設定

BASH
# 複数のキーを設定
MULTI
SET user:1:name "Alice"
SET user:1:age 25
SET user:1:email "alice@example.com"
EXEC
▶ 試してみよう

トランザクションとスクリプトの比較

Luaスクリプト(推奨)

Luaスクリプトはトランザクションよりも強力で、条件分岐やループをサポートします:

REDIS
# アトミック操作:残高が十分な場合のみ引き落とし
EVAL "
  local balance = tonumber(redis.call('GET', KEYS[1]) or 0)
  if balance >= tonumber(ARGV[1]) then
    redis.call('DECRBY', KEYS[1], ARGV[1])
    return 1
  else
    return 0
  end
" 1 balance:user:a 100

トランザクションとスクリプトの比較

機能 トランザクション Luaスクリプト
アトミック性
条件分岐
ループ
パフォーマンス 良い より良い
複雑さ シンプル より複雑

重要な注意点

⚠️ ロールバックなし: Redisのトランザクションはロールバックをサポートしていません。コマンドが失敗しても、他のコマンドは実行されます。

⚠️ コマンドエラー: 構文エラーはトランザクション全体をキャンセルします。実行時エラーは他のコマンドに影響しません。

💡 Luaスクリプト推奨: 複雑なアトミック操作には、Luaスクリプトの使用が推奨されます。

❓ よくある質問

Q Redisのトランザクションはロールバックをサポートしていますか?
A いいえ。Redisのトランザクションはロールバックをサポートしていません。ロールバック動作が必要な場合はLuaスクリプトを使用してください。
Q WATCHは何をするのですか?
A WATCHは楽観的ロックを実装します。キーを監視し、監視されたキーが変更された場合はトランザクションをキャンセルします。
Q トランザクション内のコマンドはアトミックに実行されますか?
A はい。トランザクション内のコマンドは、他のコマンドに中断されることなく順次実行されます。

📖 まとめ

📝 練習問題

  1. トランザクションの練習: MULTI/EXECを使用して複数のコマンドを実行しましょう
  2. 楽観的ロックの練習: WATCHを使用してシンプルな楽観的ロックを実装しましょう
  3. Luaスクリプトの練習: EVALを使用してLuaスクリプトを実行しましょう

次のレッスン

次のレッスンでは、Redis Persistenceについて学びます。RDBとAOFの永続化方法を解説します。

100%