面试题答案
一键面试Redis事务原子性保证机制
- 命令入队:Redis事务通过
MULTI
开启,之后的命令不会立即执行,而是被放入一个队列中。这期间即使出现语法错误等情况,命令依然会被放入队列,并不会直接执行。 - 事务执行:当
EXEC
命令被调用时,Redis会按顺序执行队列中的所有命令。在执行过程中,Redis会保证事务的原子性,即要么所有命令都执行成功,要么所有命令都不执行。这是因为在执行EXEC
时,Redis会阻塞其他客户端的命令请求,直到当前事务执行完毕。
事务执行中命令出错处理
- 入队时语法错误:如果在命令入队阶段(
MULTI
之后,EXEC
之前),某个命令存在语法错误,例如命令不存在或者参数个数不对,Redis会直接返回错误,并且不会执行后续的EXEC
操作。所有已入队的命令都不会被执行。- 示例:
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> SET key1 value1
QUEUED
127.0.0.1:6379> NON_EXISTENT_COMMAND key2 value2 # 错误命令
(error) ERR unknown command `NON_EXISTENT_COMMAND`, with args beginning with: `key2`, `value2`,
127.0.0.1:6379> SET key3 value3
QUEUED
127.0.0.1:6379> EXEC
(error) EXECABORT Transaction discarded because of previous errors.
- 运行时错误:如果命令在执行阶段(
EXEC
之后)发生错误,例如对错误的数据类型执行操作(比如对字符串类型的值执行INCR
命令,该命令通常用于数值类型),Redis会继续执行事务队列中的其他命令,而不会回滚已经执行成功的命令。- 示例:
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> SET key1 "not a number"
QUEUED
127.0.0.1:6379> INCR key1 # 对字符串执行INCR命令,运行时错误
QUEUED
127.0.0.1:6379> SET key2 value2
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) (error) ERR value is not an integer or out of range
3) OK
在这个例子中,INCR key1
命令执行出错,但SET key2 value2
命令依然会被执行。