事务的实现
事务是通过 MULTI 命令开始的,在非事务状态下客户端发送的命令会被立刻执行,而在事务状态下,除了 EXEC/WATCH/DISCARD 这几个命令外,redis 会将命令保留在事务队列里。
typedef strcut redisClient{
// 事务状态
multiState mstate;
...
}redisClient;
typedef struct multiState{
// 事务队列 FIFO
multiCmd *commands;
// 已入队命令计数
int counts;
}multiState;
typedef struct multiCmd{
// 参数
robj *args;
// 参数数量
int argc;
// 命令指针
struct redisCommand *cmd;
}multiCmd;
当一个处于事务状态的客户端向服务器发送 EXEC 命令时,服务器会遍历这个客户端的事务队列并执行队列里的所有命令,最初将执行命令后的所有后果返回给客户端。
redis 事务的 ACID
redis 是具备原子性、一致性、隔离性的,不过不具备性情的持久性。
- 对于 redis 的事务性来说,事务队列中的命令要么全副执行要么一个都不执行,不过 redis 并不反对事务的回滚,这是它与关系性数据库很大的一个区别。
- redis 是应用单线程的形式来执行事务,且事务在执行的过程中不会被中断,也就是说 redis 的事务总是以串行的形式运行的,这样其事务也就具备了隔离性。
- 事务的持久性是指一个事务执行结束时,执行这个事务所得的后果曾经被保留到了永恒存储介质里,即便服务器在事务执行后停机,执行所得的后果也不会失落。redis 将数据写入内存后,会依据长久化配置将数据同步到磁盘里,这其实是有一个滞后过程的,显然 redis 并不具备这一个性
本文参考的有:
黄健宏的《Redis 设计与实现》一书