Redis: Redis Transactions
Redisのトランザクションを使用すると、複数のコマンドを単一のユニットとして実行できます。このレッスンでは、トランザクションの使用方法と注意点について解説します。
1. トランザクションとは
トランザクションは、他のコマンドに中断されることなく順次実行されるコマンドの集合です。
BASH
MULTI → コマンド1 → コマンド2 → コマンド3 → EXEC
2. 基本コマンド
(1) MULTI:トランザクションの開始
REDIS
MULTI
OK
(2) EXEC:トランザクションの実行
REDIS
MULTI
OK
SET name "Alice"
QUEUED
SET age 25
QUEUED
EXEC
1) OK
2) OK
(3) DISCARD:トランザクションのキャンセル
REDIS
MULTI
OK
SET name "Bob"
QUEUED
DISCARD
OK
3. トランザクションのプロパティ
(1) コマンドキュー
トランザクション内のコマンドはすぐに実行されず、キューに入れられます:
REDIS
MULTI
OK
SET a 1
QUEUED
SET b 2
QUEUED
GET a
QUEUED
EXEC
1) OK
2) OK
3) "1"
(2) アトミック性
トランザクション内のコマンドは、すべて実行されるか、まったく実行されないかのどちらかです:
REDIS
MULTI
OK
SET a 1
QUEUED
SET b 2
QUEUED
EXEC
1) OK
2) OK
⚠️ 補足: Redisのトランザクションはロールバックをサポートしていません。トランザクション内でコマンドが失敗しても、他のコマンドは実行されます。
4. WATCH:楽観的ロック
WATCHはキーを監視します。監視されたキーがトランザクション実行前に変更された場合、トランザクションはキャンセルされます。
(1) 基本的な使用方法
REDIS
# キーを監視
WATCH mykey
OK
# トランザクションを開始
MULTI
OK
# キーを変更
SET mykey "new_value"
QUEUED
# トランザクションを実行
EXEC
(nil) # トランザクションがキャンセルされた場合(キーが変更された場合)はnilを返す
(2) 楽観的ロックの実装
(3) サンプル:楽観的ロック
BASH
# クライアント1
WATCH balance
GET balance
MULTI
SET balance 900
EXEC
# クライアント2(クライアント1がEXECを実行する前)
SET balance 800
5. ユースケース
(1) 在庫の引き落とし
(2) サンプル:在庫を減らす
BASH
# 在庫を減らす(アトミック操作)
MULTI
DECR stock:product:123
INCR sold:product:123
EXEC
(3) 送金
(4) サンプル:送金
BASH
# 送金:ユーザーAからユーザーBに100を送る
MULTI
DECRBY balance:user:a 100
INCRBY balance:user:b 100
EXEC
(5) バッチ操作
(6) サンプル:バッチ設定
BASH
# 複数のキーを設定
MULTI
SET user:1:name "Alice"
SET user:1:age 25
SET user:1:email "alice@example.com"
EXEC
6. トランザクションとスクリプトの比較
(1) 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
(2) トランザクションとスクリプトの比較
| 機能 | トランザクション | Luaスクリプト |
|---|---|---|
| アトミック性 | ✅ | ✅ |
| 条件分岐 | ❌ | ✅ |
| ループ | ❌ | ✅ |
| パフォーマンス | 良い | より良い |
| 複雑さ | シンプル | より複雑 |
7. 重要な注意点
⚠️ ロールバックなし: Redisのトランザクションはロールバックをサポートしていません。コマンドが失敗しても、他のコマンドは実行されます。
⚠️ コマンドエラー: 構文エラーはトランザクション全体をキャンセルします。実行時エラーは他のコマンドに影響しません。
💡 Luaスクリプト推奨: 複雑なアトミック操作には、Luaスクリプトの使用が推奨されます。
▶ サンプル
トランザクション操作:
BASH
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> SET account:A 100
QUEUED
127.0.0.1:6379> SET account:B 200
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) OK
❓ よくある質問
Q Redisのトランザクションはロールバックをサポートしていますか?
A いいえ。Redisのトランザクションはロールバックをサポートしていません。ロールバック動作が必要な場合はLuaスクリプトを使用してください。
Q WATCHは何をするのですか?
A WATCHは楽観的ロックを実装します。キーを監視し、監視されたキーが変更された場合はトランザクションをキャンセルします。
Q トランザクション内のコマンドはアトミックに実行されますか?
A はい。トランザクション内のコマンドは、他のコマンドに中断されることなく順次実行されます。
📖 まとめ
- MULTIでトランザクションを開始、EXECで実行、DISCARDでキャンセル
- コマンドはトランザクション内でキューに入れられ、EXECで順次実行
- WATCHは楽観的ロックを提供し、キーの変更を監視
- Redisのトランザクションはロールバックをサポートしない
- 複雑なアトミック操作にはLuaスクリプトが推奨
📝 練習問題
- トランザクションの練習: MULTI/EXECを使用して複数のコマンドを実行しましょう
- 楽観的ロックの練習: WATCHを使用してシンプルな楽観的ロックを実装しましょう
- Luaスクリプトの練習: EVALを使用してLuaスクリプトを実行しましょう
8. 次のレッスン
次のレッスンでは、Redis Persistenceについて学びます。RDBとAOFの永続化方法を解説します。