前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redis:17---常用功能之(事务)

Redis:17---常用功能之(事务)

作者头像
用户3479834
发布2021-02-03 12:57:18
5010
发布2021-02-03 12:57:18
举报
文章被收录于专栏:游戏开发司机
  • 为了保证多条命令组合的原子性,Redis提供了简单的事务功能以及集成Lua脚本来解决这个问题,本文介绍Redis事务,Lua在下一篇文章介绍

一、事务概述

  • 简单地说,事务表示一组动作,要么全部执行,要么全部不执行。例如在社交网站上用户A关注了用户B,那么需要在用户A的关注表中加入用户B,并且在用户B的粉丝表中添加用户A,这两个行为要么全部执行,要么全部不执行,否则会出现数据不一致的情况
  • Redis只提供了四个命令管理事务:
    • MULTI:用来开启一个事务。开启一个事务之后,输入的命令不会被立即执行,而是进入事务队列中(入队),所以可以看见输入命令的结果显示为“QUEUED”
    • WATCH:是一个乐观锁。它可以在EXEC命令执行之前,监视任意数量的数据库键,并在EXEC命令执行时,检查被监视的键是否至少有一个已经被修改过了,如果是的话,服务器将拒绝执行事务,并向客户端返回代表事务执行失败的空回复
    • DISCARD:用于取消本次事务,放弃执行事务块内的所有命令。如果使用了WATCH,DISCARD将取消监视连接监视的所有键
    • EXEC:提交一个事务
  • 所以Redis的事务比较简单,主要是因为它不支持事务中的回滚特性,同时无法实现命令之间的逻辑关系计算,当然也体现了Redis的“keep it simple”的特性

二、事务演示案例

MULTI+EXEC

  • 下面使用MULTI开启一个事务,并且执行相关操作,最后使用EXEC提交执行事务内的操作
  • 备注:可以看到事务开启之后,每次执行的命令结果都会显示QUEUED,表示命令入队,但是没有被执行

MULTI+DISCARD

  • 下面使用MULTI开启一个事务,并且执行相关操作,最后使用DISCARD终止本次事务,并且事务内的操作全部放弃执行
  • 备注:因为discard已经结束事务了,所以再次输入exec会显示没有匹配的multi

MULTI+WATCH+EXEC

  • 客户端1:先设置一个字符串,键名为key,然后使用watch监听该键。然后开启事务
  • 客户端2:在客户端1事务还未结束的时候,修改key
  • 客户端1:操作key,并提交事务。因为key被其他客户端修改,所以EXEC返回nil,事务没有被执行。然后获取key,key没有被改变

三、事务错误的处理

  • 如果事务中出现错误,那么Reiis的处理机制也不尽相同

①命令错误

  • 如果一个事务在入队命令的过程中,出现了命令不存在,或者命令的格式不正确等情况,那么Redis将拒绝执行这个事务
  • 例如:下面操作错将set写成了sett,属于语法错误,会造成整个事务无法执行,key和counter的值未发生变化:

根据文档记录,在Redis 2.6.5以前的版本,即使有命令在入队过程中发生了错误, 事务一样可以执行,不过被执行的命令只包括那些正确入队的命令,以下这段代码是 在Redis 2.6.4版本上测试的,可以看到事务可以正常执行,但只有成功入队的SET命令 和GET命令被执行了,而错误的YAH000O则被忽略了:

代码语言:javascript
复制
redis> MULTI
OK
redis> SET msg "hello"
QUEUED
redis> YAH000O
(error) ERR unknown command ' YAH000O'
redis> GET msg
QUEUED
redis> EXEC
11 OK
2) "hello"

②运行时错误(执行错误)

  • 有些事务输入的命令没有错误,但是语法或逻辑有错误,这类错误不会被立即检测出来,只有当事务提交时才会被检测出来
  • 即使在事务的执行过程中发生了错误,服务器也不会中断事务的执行,它会继续执行事务中余下的其他命令,并且已执行的命令(包括执行命令所产生的结果)不会被出错的命令影响
  • 因为在事务执行的过程中,出错的命令会被服务器识别出来,并进行相应的错误处理, 所以这些出错命令不会对数据库做任何修改,也不会对事务的一致性产生任何影响

③服务器停机

  • 如果Redis服务器在执行事务的过程中停机,那么根据服务器所使用的持久化模式,可能有以下情况出现:
    • 如果服务器运行在无持久化的内存模式下,那么重启之后的数据库将是空白的,因此数据总是一致的
    • 如果服务器运行在RDB模式下,那么在事务中途停机不会导致不一致性,因为服务器可以根据现有的RDB文件来恢复数据,从而将数据库还原到一个一致的状态。如果找不到可供使用的RDB文件,那么重启之后的数据库将是空白的,而空白数据库总是一致的
    • 如果服务器运行在AOF模式下,那么在事务中途停机不会导致不一致性,因为服务器可以根据现有的AOF文件来恢复数据,从而将数据库还原到一个一致的状态。如果找不到可供使用的AOF文件,那么重启之后的数据库将是空白的,而空白数据库总是一致的
  • 综上所述,无论Redis服务器运行在哪种持久化模式下,事务执行中途发生的停机都不会影响数据库的一致性
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-12-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 游戏开发司机 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、事务概述
  • 二、事务演示案例
    • MULTI+EXEC
      • MULTI+DISCARD
        • MULTI+WATCH+EXEC
        • 三、事务错误的处理
          • ①命令错误
            • ②运行时错误(执行错误)
              • ③服务器停机
              相关产品与服务
              云数据库 Redis®
              腾讯云数据库 Redis®(TencentDB for Redis®)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档