用裸RESP协议手动发MULTI/命令/EXEC,逐条观察排队阶段和真正执行阶段分别发生了什么。
不用客户端库包装,直接拼RESP协议帧,看服务器每一步回了什么。
代码import socket s = socket.create_connection(("127.0.0.1", 19379)) def cmd(sock, *args): msg = f"*{len(args)}\r\n" for a in args: msg += f"${len(str(a))}\r\n{a}\r\n" sock.sendall(msg.encode()) return sock.recv(65536) print(cmd(s, "MULTI")) print(cmd(s, "SET", "counter", "20")) print(cmd(s, "INCR", "counter"))
SET和INCR本该有自己的返回值(+OK和一个整数),收到的却完全不是这些。
结果MULTI → +OK SET counter 20 → +QUEUED (不是+OK!) INCR counter → +QUEUED (不是:21!)
验证了:进入MULTI状态后,服务器对后续每一条命令只做了两件事——检查这条命令本身是否存在、参数格式是否合法,然后把它原样放进一个队列,立刻回复+QUEUED,命令的业务逻辑(改数据、算结果)在这一步完全没有被执行。
这一批命令里故意混了一条会在运行时报错的LPUSH。
代码与结果MULTI SET counter 20 → QUEUED INCR counter → QUEUED LPUSH counter x → QUEUED (counter是字符串,这条命令注定会失败) SET another 1 → QUEUED EXEC → 返回: [+OK, :21, -WRONGTYPE Operation against a key holding the wrong kind of value, +OK]
每一步都是本文上面用裸RESP协议跑出来的原始结果。