DBAtlas · データベース運用アトラス

ERR WATCH inside MULTI is not allowed: WATCH inside MULTI is not allowed(MULTI 内の WATCH は許可されない)

Redis

意味

開いている MULTI ブロック内で WATCH が送信された。楽観的ロックのため、WATCH はトランザクション開始前にキーを監視対象にする必要があり、MULTI の後に呼び出すと拒否される。このエラーでトランザクションは中止されず、WATCH のみが失敗し、何も監視されない。

原因

コード内で WATCH と MULTI の順序が逆になっている (先に MULTI、次に WATCH)、クライアントライブラリのパイプライン/トランザクションラッパー内で WATCH を呼び出している、または MULTI 状態のまま残されたプール接続を使用している。この場合、監視されるはずのキーが変更されても EXEC が実行され、想定した競合保護が働かない。

対処方法

正しい順序: WATCH key -> (値を読み取る) -> MULTI -> コマンド -> EXEC。EXEC が nil を返した場合は監視対象のキーが変更されたので、操作を最初からやり直す。クライアントライブラリの WATCH/トランザクション API (例: watch + パイプラインのヘルパー) を使用する。注: SUBSCRIBE などの pub/sub コマンドは MULTI 内で拒否されず、キューに入れられ、EXEC 後に接続が subscribe モードに切り替わる。これも推奨されないため、pub/sub には専用の接続を使用する。

DBAtlas で開く →

同じデータベースの他の項目