Redis 事务

在这里插入图片描述

1、什么是事务

Redis 通过 MULTI、EXEC、WATCH 等命令来实现事务功能。Redis 的事务提供了一种将多个命令请求打包,按顺序放入事务队列,然后一次性、顺序性、排他性地执行这些命令。即在事务执行期间,服务器是不会中断事务而去处理其他客户端的命令请求的,它会将事务中的所有命令都执行完毕后,再去处理其他客户端的请求。

2、Redis 事务的相关命令

  • MULTI:用于标识一个事务的开始,将执行该命令的客户端从非事务状态切换至事务状态,这一切换是通过在客户端状态的 flags 属性中打开 REDIS_MULTI 标识来完成的。
  • EXEC:执行事务队列中的所有命令。
  • WATCH:用于标记要监视的 key,以便有条件地执行事务。WATCH 命令可以监控一个或多个键,一旦监视的键被修改 / 删除,事务将被拒绝执行。
  • UNWATCH:取消 WATCH 命令对所有 key 的监视,如果执行 EXEC 或 DISCARD 命令,则无需再执行 UNWATCH 命令。【因为执行 EXEC 或 DISCARD 命令的同时也取消了对所有 key 的监视】
  • DISCARD:取消事务的命令,放弃执行事务队列内的所有命令,客户端状态恢复为非事务状态;如果正在使用 WATCH 命令监视某个(或某些)key,那么取消所有监视,等同于执行命令 UNWATCH。

3、事务的实现

3.1 事务开始

在这里插入图片描述

3.2 命令入队

当一个客户端处于非事务状态时,这个客户端发送的命令会被服务器立即执行。当一个客户端切换到事务状态后,服务器会根据这个客户端发来的不同命令执行不同的操作。
在这里插入图片描述

3.2.1 事务队列

每个 Redis 客户端都有自己的事务状态,对应的是客户端状态(redisClient)的 mstate 属性。

typedef struct redisClient{
    multiState mstate;	//事务状态
}
redisClient;

事务状态(mstate)包含一个事务队列(FIFO 队列),以及一个已入队命令的计数器。

typedef struct multiState {
    // 事务队列,FIFO 顺序
    multiCmd *commands;
    /* Array of MULTI commands */
    // 已入队命令计数
    int count;
    //......
} multiState;

事务队列是一个 multiCmd 类型数组,数组中每个 multiCmd 结构都保存了一个入队命令的相关信息:指向命令实现函数的指针,命令的参数,以及参数的数量。

typedef struct multiCmd {
    // 参数
    robj **argv;
    // 参数数量
    int argc;
    // 命令指针
    struct redisCommand *cmd;
} multiCmd;

事务队列以先进先出(FIFO)的方式保存入队的命令,较先入队的命令会被放在数组的前面。

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> SET "name" "Practical Commom Lisp"
QUEUED
127.0.0.1:6379> GET "name"
QUEUED
127.0.0.1:6379> SET "author" "Peter Seibel"
QUEUED
127.0.0.1:6379> GET "author"
QUEUED

在这里插入图片描述
如果命令入队出错时,会打开客户端状态 REDIS_DIRTY_EXEC。

3.3 事务执行

客户端发送 EXEC 命令,服务器执行 EXEC 命令逻辑。

  • 如果客户端状态的 flags 属性不包含 REDIS_MULTI 标识,或者包含 REDIS_DIRTY_CAS 或者 REDIS_DIRTY_EXEC 标识,那么就直接取消事务的执行。【REDIS_DIRTY_EXEC --> 入队命令出错,REDIS_DIRTY_CAS --> 监视的键被修改 / 删除】
  • 否则客户端处于事务状态(flags 有 REDIS_MULTI 标识),服务器会遍历客户端的事务队列,然后执行事务队列中的所有命令,最后将返回结果全部返回给客户端;

4、WATCH 命令实现

在这里插入图片描述

4.1 监视机制的触发

在这里插入图片描述

5、Redis 事务的 ACID 性质

https://zhuanlan.zhihu.com/p/144268090

在这里插入图片描述

5.1 原子性

在这里插入图片描述
在这里插入图片描述

5.2 一致性

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.3 隔离性

在这里插入图片描述

5.4 持久性

在这里插入图片描述
在这里插入图片描述

X、小结

Redis 事务总具有 ACID 中的原子性、一致性和隔离性,当服务器运行再 AOF 持久化模式下,并且 appendfsync 选项的值为 always 时,事务也具有持久性,否则不具持久性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值