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命令的实现相关推荐

  1. Redis事务入门及命令

    文章目录 Redis 事务入门及命令 事务概念 Redis 事务概念 Redis 事务特性 Redis 三个阶段 入门代码示例 Redis 相关命令 MULTI DISCARD EXEC WATCH ...

  2. Redis事务、MULTI 命令和EXEC 命令

    Redis事务 文章目录 Redis事务 事务实例 MULTI 命令 EXEC 命令 事务异常 1. 进入队列之前发生错误 Redis 是没有回滚操作的 Watch 命令 执行 watch 命令,不执 ...

  3. Redis事务,watch命令学习

    redis事务: redis的事务和mysql等关系型数据库的事务不太一样,redis中的事务不会回滚,只能手动收拾事务失败后的烂摊子. 在命令行中,MULTI是事务的开始命令.EXEC是事务的执行命 ...

  4. redis 系列二 -- 常用命令

    2019独角兽企业重金招聘Python工程师标准>>> 1.基础命令 info    ping    quit    save dbsize    select    flushdb ...

  5. Redis事务控制|相关命令|队列失败两种情况|官方解释无回滚|悲观锁和乐观锁简单介绍

    相关命令 命令队列执行失败的两种情况 1.执行队列时失败:错误在入队时检测不出来,整个队列执行时有错的命令执行失败,但是其他命令并没有回滚. 加入队列时失败:遇到了入队时即可检测到的错误,整个队列都不 ...

  6. 面试问到 Redis 事务,我脸都绿了。。

    前言 前几天有读者说自己面试被问到Redis的事务,虽然不常用,但是面试竟然被问到,平时自己没有注意Redis的事务这一块,面试的时候被问到非常不好受. 虽然,这位读者面试最后算是过了,但是薪资方面没 ...

  7. Redis : redis事务

    Redis的事务功能详解 MULTI.EXEC.DISCARD和WATCH命令是Redis事务功能的基础. Redis事务允许在一次单独的步骤中执行一组命令,并且可以保证如下两个重要事项: >R ...

  8. 分布式内存数据库--Redis事务

    一. 事务: 与关系型数据库一样redis也支持事务.也就是可以一次执行多个命令,本质是一组命令的集合.一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞. 二. 事务能 ...

  9. Redis事务深入解析和使用

    作为关系型数据库中一项非常重要的基础功能--事务,在 Redis 中是如何处理并使用的? 1.前言 事务指的是提供一种将多个命令打包,一次性按顺序地执行的机制,并且保证服务器只有在执行完事务中的所有命 ...

最新文章

  1. sql 70-229 考试样题(1)
  2. Django博客系统(文章分类模型)
  3. mxnet保存模型,加载模型来预测新数据
  4. 训练集数量对神经网络光谱的影响
  5. gimp教程:gimp界面介绍
  6. PMP读书笔记(第6章)
  7. windows下最好的C++ IDE
  8. spring@Autowired的对象为null,非容器中的类如何调用容器中的类
  9. NSRunLoop 概述和原理
  10. 魔幻的2020年,请程序员们收下这份秋招建议!
  11. Django之Form组件补充
  12. AD模块电压采集电路
  13. java用switch语句抽奖_Java使用带有switch语句的枚举
  14. 冯诺伊曼体系结构建模与模拟 之TOY模型机※
  15. Coder, 知道 《编码》吗?
  16. vue项目中-上传图片头像并裁剪成任意大小的实现
  17. Cadence OrCAD Capture 检索和定位功能的介绍图文视频教程
  18. 梦之旅游戏攻略html5,《梦之旅1:梦境》攻略
  19. 计算机游戏教学中教师,计算机游戏教学法在信息技术教学中的运用
  20. #19ACM第一次招新补题赛de题解呐#

热门文章

  1. 我的3轴4轴并联机器人
  2. 异步height:calc_异步:不仅仅是承诺(第二部分)
  3. 华为畅享20为什么没有计算机,使用后说说华为畅享20pro和荣耀20pro的有区别没有?哪个好?全方位深度解析实情...
  4. 30年房贷到底要不要提前还?
  5. [gdc10][animphysics]《正当防卫2》的动画技术
  6. Prometheus===》普罗米修斯容器化监控、PromQL的使用、Grafana添加普罗米修斯数据源模板
  7. d3.js 旋转图形_“学习思路给你,看了就会”:小学数学知识点《组合图形的面积》...
  8. 爬虫练习四:爬取b站番剧字幕
  9. 如何将列的数字编号,转化为EXcel的字母表示的列编号
  10. VIM快捷键大全(附图片一张)