
| 命令英文 | 命令中文 | 成功 | 失败 | 解释 | |
|---|---|---|---|---|---|
| multi | 开启事务 | OK | |||
| set/get… | 各种命令 | 全都返回"QUEUED" |
整个事务取消,但不会回滚之前的命令 | ||
| watch key | 监视 | exec成功 | exec失败 | watch到exec这段时间值被其他客户端改了exec就错误 | |
| exec | 执行事务 | 返回所有的结果 | (nil) |
||
| discard | 取消事务 |
Redis 作者认为发生事务回滚的原因大部分都是程序错误导致,这种情况一般发生在开发和测试阶段,而生产环境很少出现。对于逻辑性错误,比如本来应该把一个数加 1 ,但是程序逻辑写成了加 2,那么这种错误也是无法通过事务回滚来进行解决的。Redis 追求的是简单高效,而传统事务的实现相对比较复杂,这和 Redis 的设计思想相违背。
总结:redis不会错,错了就是你的错,我就这样
C - 一致性一致性指的就是事务执行前后的数据符合数据库的定义和要求。这一点 Redis 中的事务是符合要求的,上面讲述原子性的时候已经提到,不论是发生语法错误还是运行时错误,错误的命令均不会被执行。I - 隔离性事务中的所有命令都会按顺序执行,在执行 Redis 事务的过程中,另一个客户端发出的请求不可能被服务,这保证了命令是作为单独的独立操作执行的。所以 Redis 当中的事务是符合隔离性要求的。D - 持久性如果 Redis 当中没有被开启持久化,那么就是纯内存运行的,一旦重启,所有数据都会丢失,此时可以认为 Redis 不具备事务的持久性;而如果 Redis 开启了持久化,那么可以认为 Redis 在特定条件下是具备持久性的。
Redis 中每个客户端都有记录当前客户端的事务状态 multiState,下面就是一个客户端 client 的数据结构定义:typedef struct client {uint64_t id;//客户端唯一 idmultiState mstate; //MULTI 和 EXEC 状态(即事务状态)//...省略其他属性} client;multiState 数据结构定义如下:typedef struct multiState {multiCmd *commands;//存储命令的 FIFO 队列int count;//命令总数//...省略了其他属性} multiState;multiCmd 是一个队列,用来接收并存储开启事务之后发送的命令,其数据结构定义如下:typedef struct multiCmd {robj **argv;//用来存储参数的数组int argc;//参数的数量struct redisCommand *cmd;//命令指针} multiCmd;