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 はい。トランザクション内のコマンドは、他のコマンドに中断されることなく順次実行されます。

📖 まとめ

📝 練習問題

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

8. 次のレッスン

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

Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%