ERR WATCH inside MULTI is not allowed: WATCH inside MULTI is not allowed
Redis의미
열린 MULTI 블록 안에서 WATCH를 보냈다. 낙관적 락을 위해 WATCH는 트랜잭션이 시작되기 전에 키를 감시 대상으로 등록해야 하며, MULTI 이후에 호출하면 거부된다. 이 오류는 트랜잭션을 중단하지 않으며 WATCH만 실패하고 아무것도 감시되지 않는다.
원인
코드에서 WATCH와 MULTI의 순서가 반대로 작성되었거나(MULTI 먼저, 그다음 WATCH), 클라이언트 라이브러리의 pipeline/트랜잭션 래퍼 안에서 WATCH를 호출했거나, MULTI 상태로 남은 풀 연결을 사용한 경우다. 이 경우 감시되어야 할 키가 변경되어도 EXEC가 실행되므로 기대한 충돌 보호가 동작하지 않는다.
해결 방법
올바른 순서: WATCH key -> (값 읽기) -> MULTI -> 명령 -> EXEC. EXEC가 nil을 반환하면 감시한 키가 변경된 것이므로 작업을 처음부터 재시도한다. 클라이언트 라이브러리의 WATCH/트랜잭션 API(예: watch + pipeline 헬퍼)를 사용한다. 참고: SUBSCRIBE 같은 pub/sub 명령은 MULTI 안에서 거부되지 않고 큐에 쌓이며, EXEC 후 연결이 subscribe 모드로 전환된다. 이것도 권장되지 않으므로 pub/sub에는 전용 연결을 사용한다.
같은 데이터베이스의 다른 항목
- ERR bit offset is not an integer or out of rangeBit offset is not an integer or out of range (비트 오프셋이 정수가 아니거나 범위를 벗어남)
- ERR Protocol error: invalid multibulk lengthProtocol error: invalid multibulk length (프로토콜 오류: 유효하지 않은 multibulk 길이)
- ERR Number of keys can't be greater than number of argsEVAL/EVALSHA: numkeys exceeds argument count (numkeys가 인수 개수를 초과)
- ERR WAIT cannot be used with replica instancesWAIT cannot be used with replica instances (replica 인스턴스에서는 WAIT 사용 불가)
- ERR Background append only file rewriting already in progressAOF rewrite already in progress
- IOERR error or timeout reading from target instanceMIGRATE: I/O error or timeout to target
- ERR Error compiling script (new function)Error compiling Lua script