Redis事务(二)-WATCH命令的实现
WATCH命令的实现
- 概述
- 使用WATCH命令监视数据库键
- 监视机制的触发
- 判断事务是否安全
概述
WATCH命令是一个乐观锁(optimistic locking)
它可以在EXEC命令执行之前,监视 任意数量 的数据库键
并在EXEC命令执行时,检查 被监视的键 是否 至少有一个 已经被修改过了
如果是的话,服务器将拒绝执行事务,并向 客户端 返回 代表事务执行失败的空回复,举例如下:
redis> WATCH "name"
OK
redis> MULTI
OK
redis> SET "name" "peter"
QUEUED
redis> EXEC
(nil)
来看一下
在时间T4,客户端B修改了"name"键的值,当客户端A在T5执行EXEC命令时,服务器会发现WATCH监视的键"name"已经被修改,因此服务器拒绝执行客户端A的事务,并向客户端A返回空回复
使用WATCH命令监视数据库键
每个Redis数据库 都保存着一个 watched_keys
字典
- 字典 的 键(key) 是 某(些)个 被WATCH命令监视的 数据库键,就是缓存key
- 字典的值 则是一个 链表,链表中 记录了 所有监视相应数据库键(缓存key) 的 客户端
typedef struct redisDb {// ...//
正在被WATCH
命令监视的键dict *watched_keys;// ...
} redisDb;
通过watched_keys字典,服务器 可以清楚地知道 哪些数据库键 正在被监视,以及 哪些客户端 正在监视 这些数据库键,如下:
- 客户端c1和c2正在监视键"name"
- 客户端c3正在监视键"age"
- 客户端c2和c4正在监视键"address"
监视机制的触发
所有对数据库进行修改的命令,比如SET、LPUSH、SADD、ZREM、DEL、FLUSHDB等等,在执行之后都会调用multi.c/touchWatchKey
函数对watched_keys
字典进行检查,查看 是否有客户端 正在监视 刚刚被命令修改过的数据库键
如果有的话,那么touchWatchKey
函数 会将 监视被修改键 的 客户端 的 REDIS_DIRTY_CAS
标识打开,表示该客户端的事务安全性已经被破坏
touchWatchKey函数的定义可以用以下伪代码来描述:
def touchWatchKey(db, key):#
如果键key
存在于数据库的watched_keys
字典中#
那么说明至少有一个客户端在监视这个keyif key in db.watched_keys:#
遍历所有监视键key
的客户端for client in db.watched_keys[key]:#
打开标识client.flags |= REDIS_DIRTY_CAS
判断事务是否安全
当服务器接收到一个客户端发来的EXEC命令时
服务器会根据这个客户端是否打开了REDIS_DIRTY_CAS
标识来决定是否执行事务
- 如果客户端的
REDIS_DIRTY_CAS
标识已经被打开,那么说明客户端所监视的键当中,至少有一个键已经被修改过了,在这种情况下,客户端提交的事务已经不再安全,所以服务器会拒绝执行客户端提交的事务 - 如果客户端的
REDIS_DIRTY_CAS
标识没有被打开,那么说明客户端监视的所有键都没有被修改过(或者客户端没有监视任何键),事务仍然是安全的,服务器将执行客户端提交的这个事务
Redis事务(二)-WATCH命令的实现相关推荐
- Redis事务入门及命令
文章目录 Redis 事务入门及命令 事务概念 Redis 事务概念 Redis 事务特性 Redis 三个阶段 入门代码示例 Redis 相关命令 MULTI DISCARD EXEC WATCH ...
- Redis事务、MULTI 命令和EXEC 命令
Redis事务 文章目录 Redis事务 事务实例 MULTI 命令 EXEC 命令 事务异常 1. 进入队列之前发生错误 Redis 是没有回滚操作的 Watch 命令 执行 watch 命令,不执 ...
- Redis事务,watch命令学习
redis事务: redis的事务和mysql等关系型数据库的事务不太一样,redis中的事务不会回滚,只能手动收拾事务失败后的烂摊子. 在命令行中,MULTI是事务的开始命令.EXEC是事务的执行命 ...
- redis 系列二 -- 常用命令
2019独角兽企业重金招聘Python工程师标准>>> 1.基础命令 info ping quit save dbsize select flushdb ...
- Redis事务控制|相关命令|队列失败两种情况|官方解释无回滚|悲观锁和乐观锁简单介绍
相关命令 命令队列执行失败的两种情况 1.执行队列时失败:错误在入队时检测不出来,整个队列执行时有错的命令执行失败,但是其他命令并没有回滚. 加入队列时失败:遇到了入队时即可检测到的错误,整个队列都不 ...
- 面试问到 Redis 事务,我脸都绿了。。
前言 前几天有读者说自己面试被问到Redis的事务,虽然不常用,但是面试竟然被问到,平时自己没有注意Redis的事务这一块,面试的时候被问到非常不好受. 虽然,这位读者面试最后算是过了,但是薪资方面没 ...
- Redis : redis事务
Redis的事务功能详解 MULTI.EXEC.DISCARD和WATCH命令是Redis事务功能的基础. Redis事务允许在一次单独的步骤中执行一组命令,并且可以保证如下两个重要事项: >R ...
- 分布式内存数据库--Redis事务
一. 事务: 与关系型数据库一样redis也支持事务.也就是可以一次执行多个命令,本质是一组命令的集合.一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞. 二. 事务能 ...
- Redis事务深入解析和使用
作为关系型数据库中一项非常重要的基础功能--事务,在 Redis 中是如何处理并使用的? 1.前言 事务指的是提供一种将多个命令打包,一次性按顺序地执行的机制,并且保证服务器只有在执行完事务中的所有命 ...
最新文章
- sql 70-229 考试样题(1)
- Django博客系统(文章分类模型)
- mxnet保存模型,加载模型来预测新数据
- 训练集数量对神经网络光谱的影响
- gimp教程:gimp界面介绍
- PMP读书笔记(第6章)
- windows下最好的C++ IDE
- spring@Autowired的对象为null,非容器中的类如何调用容器中的类
- NSRunLoop 概述和原理
- 魔幻的2020年,请程序员们收下这份秋招建议!
- Django之Form组件补充
- AD模块电压采集电路
- java用switch语句抽奖_Java使用带有switch语句的枚举
- 冯诺伊曼体系结构建模与模拟 之TOY模型机※
- Coder, 知道 《编码》吗?
- vue项目中-上传图片头像并裁剪成任意大小的实现
- Cadence OrCAD Capture 检索和定位功能的介绍图文视频教程
- 梦之旅游戏攻略html5,《梦之旅1:梦境》攻略
- 计算机游戏教学中教师,计算机游戏教学法在信息技术教学中的运用
- #19ACM第一次招新补题赛de题解呐#
热门文章
- 我的3轴4轴并联机器人
- 异步height:calc_异步:不仅仅是承诺(第二部分)
- 华为畅享20为什么没有计算机,使用后说说华为畅享20pro和荣耀20pro的有区别没有?哪个好?全方位深度解析实情...
- 30年房贷到底要不要提前还?
- [gdc10][animphysics]《正当防卫2》的动画技术
- Prometheus===》普罗米修斯容器化监控、PromQL的使用、Grafana添加普罗米修斯数据源模板
- d3.js 旋转图形_“学习思路给你,看了就会”:小学数学知识点《组合图形的面积》...
- 爬虫练习四:爬取b站番剧字幕
- 如何将列的数字编号,转化为EXcel的字母表示的列编号
- VIM快捷键大全(附图片一张)