一、WATCH命令介绍

  • WATCH命令是一个乐观锁(optimistic locking)
  • 功能: 它可以在EXEC命令执行之前,监视任意数量的数据库键,并在EXEC命令执行时,检查被监视的键是否至少有一个已经被修改过了,如果是的话,服务器将拒绝执行事务,并向客户端返回代表事务执行失败的空回复

演示案例

  • 以下是一个事务执行失败的例子:

    在时间T4,客户端B修改了"name"键的值,当客户端A在T5执行EXEC命令时,服务器会发现WATCH监视的键"name"已经被修改,因此服务器拒绝执行客户端A的事务,并向客户端A返回空回复

二、使用WATCH命令监视数据库键(watched_keys字典)

每个Redis数据库都保存着一个watched_keys字典:

  • 字典的键是某个被WATCH命令 监视的数据库键
  • 字典的值则是一个链表,链表中记录了所有监视相应数据库键的客户端
typedef struct redisDb {// ...//正在被WATCH 命令监视的键dict *watched_keys;// ...
} redisDb;
  • 通过watched_key s字典,服务器可以清楚地知道哪些数据库键正在被监视,以及哪些客户端正在监视这些数据库键

下图是一个watched_keys字典的示例,从这个watched_keys字典中可以看出:

  • 客户端c1和c2正在监视键"name"
  • 客户端c3正在监视键"age"
  • 客户端c2和c4正在监视键"address"


通过执行WATCH命令,客户端可以在watched_keys字典中与被监视的键进行关联。举个例子,如果当前客户端为c10086,那么客户端执行以下WATCH命令之后:


上图展示的watched_keys字典将被更新至下图所示的状态,其中用虚线包围的两个c10086节点就是由刚刚执行的WATCH命令添加到字典中的

三、监视机制的触发(touchWatchKey函数、REDIS_DIRTY_CAS标识)

所有对数据库进行修改的命令,比如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

举个例子,对于下图所示的watched_keys字典来说:

  • 如果键"name"被修改,那么c1、c2、c10086三个客户端的REDIS_DIRTY_CAS标识将被 打开
  • 如果键"age"被修改,那么c3和c10086两个客户端的REDIS_DIRTY_CAS标识将被打开
  • 如果键"address"被修改,那么c2和c4两个客户端的REDIS_DIRTY_CAS标识将被打开

四、判断事务是否安全

当服务器接收到一个客户端发来的EXEC命令时,服务器会根据这个客户端是否打开了REDIS_DIRTY_CAS标识来决定是否执行事务:

  • 如果客户端的REDIS_DIRTY_CAS标识已经被打开,那么说明客户端所监视的键当中,至少有一个键已经被修改过了,在这种情况下,客户端提交的事务已经不再安全,所以服务 器会拒绝执行客户端提交的事务
  • 如果客户端的REDIS_DIRTY_CAS标识没有被打开,那么说明客户端监视的所有键都没有被修改过(或者客户端没有监视任何键),事务仍然是安全的,服务器将执行客户端提交的这个事务

这个判断是否执行事务的过程可以下面的流程图来描述

Redis(设计与实现):---事务之WATCH命令(watched_keys字典、touchWatchKey函数、REDIS_DIRTY_CAS标识)相关推荐

  1. 【Redis学习】Transaction事务管理

    1.相关命令: (1)MULTI 标记一个事务块的开始.事务块内的多条命令会按照先后顺序被放进一个队列当中,最后由 EXEC 命令原子性(atomic)地执行. 返回值:总是返回 OK . redis ...

  2. Redis | 第8章 发布订阅与事务《Redis设计与实现》

    第8章 发布订阅与事务 前言 1. 发布订阅 1.1 频道的订阅与退订 1.2 模式的订阅与退订 1.3 发送消息 1.4 查看订阅消息 2. 事务 2.1 事务的实现 2.2 WATCH 命令的实现 ...

  3. Redis的事务:相关命令 watch 与mysql事务的区别

    Redis事务的概念: Redis 事务的本质是一组命令的集合. 事务支持一次执行多个命令,一个事务中所有命令都会被序列化.在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求不 ...

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

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

  5. Redis事务入门及命令

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

  6. Redis事务(二)-WATCH命令的实现

    WATCH命令的实现 概述 使用WATCH命令监视数据库键 监视机制的触发 判断事务是否安全 概述 WATCH命令是一个乐观锁(optimistic locking) 它可以在EXEC命令执行之前,监 ...

  7. Redis事务,watch命令学习

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

  8. 《Redis设计与实现》笔记|SDS动态字符串|链表字典跳跃表整数集合压缩列表结构|redis中的对象|数据库原理|RDB持久化|AOF持久化|事件与多路利用模型|发布订阅原理|事务原理|慢查询日志

    <Redis设计与实现>笔记 前记: 参考配套网站:http://redisbook.com 带注释的源码地址:https://github.com/huangz1990/redis-3. ...

  9. 《redis 设计与实现》读书笔记

    大家好,我是烤鸭:     <redis 设计与实现>,读书笔记. 第一部分 数据结构与对象 第2章 简单动态字符串 Redis 使用SDS 作为字符串表示. O(1) 复杂度获取字符串长 ...

最新文章

  1. 了解大脑的“小情绪”,轻松成为“效率达人”
  2. 域控服务器发生w32time错误
  3. EMC CLARiiON 的 Alignment offset
  4. iOS开发那些事-平铺导航–基于分屏导航及案例实现
  5. 乱乱乱!那些惨不忍睹的机房布线
  6. C语言学习记录_2019.02.02
  7. 密码学笔记——zip明文攻击
  8. python获取文件路径下指定的类型的文件_python学习1-列出指定目录下的指定类型文件...
  9. Swift class和struct的解归档
  10. 一款支持vue3 的颜色选择器
  11. html连接有道词典api,调用有道翻译API
  12. 深信服虚拟化服务器,深信服虚拟化asv体验
  13. http库三剑客:httpx
  14. 第四章 Sysrepo连接与会话
  15. 删除的android电话怎么找回,通话记录删除了怎么恢复?安卓手机通话记录恢复方法...
  16. [转]电烙铁的使用小技巧
  17. Centos挂载fat32格式的u盘和ntfs格式的移动硬盘
  18. dellr720服务器性能,戴尔服务器R720
  19. 电脑病毒怎么彻底清理?你不知道的8个方法
  20. mysql删除不彻底,mysql删除不彻底的解决方法

热门文章

  1. java开发环境的搭建及配置
  2. 开发使用air还是pro_搭载 M1 芯片的 MacBook Air/Pro 值得买吗?
  3. Windows下whl文件安装
  4. APP修改包名后依然覆盖 注意事项
  5. 火狐Firefox定制安装包制作流程
  6. PerfDog 测试腾讯视频、优酷、爱奇艺视频类小程序性能
  7. Windows系统 清理C盘详细步骤
  8. 计算机中的画图如何写字,请问怎样在电脑中的图片上面写字?
  9. (6K字!)从零实现vue3响应式系统!
  10. 关于约束 和事务、DDL与 DML语句