Redis 事务详解

一、Redis 事务和Mysql 事务的区别

1、mysql中只有使用了InnoDB引擎的数据库或表才支持事务;
2、使用“事务”的目的是:可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序串行化的执行而不会被其他命令插入

二、Redis 事务指令

Redis事务涉及到MULTI, EXEC, DISCARD, WATCHUNWATCH这五个命令:

  • MULTI:事务开始的命令是MULTI, 该命令返回OK提示信息. MULTI 执行之后, 客户端可以继续向服务器发送任意多条命令, 这些命令不会立即被执行, 而是被放到一个队列中, 当 EXEC命令被调用时, 所有队列中的命令才会被执行。通过调用 DISCARD , 客户端可以清空事务队列, 并放弃执行事务
  • EXEC: 是事务的提交命令,当客户端处于事务状态时, 所有传入的 编译/语法 正确命令都会返回一个内容为 QUEUED 的状态回复(status reply), 这些被入队的命令将在 EXEC 命令被调用时依次执行。该命令将返回响应数组,数组中的每个元素都是执行事务中的命令所产生的回复。 其中, 回复元素的先后顺序和命令发送的先后顺序一致。
  • WATCH: watch命令是一个乐观锁,它可以在exec命令执行之前,监视任意数量的数据库键,并在exec命令执行时,检查被监视的键是否至少有一个已经被修改过,如果是的话,服务器将拒绝执行事务,并向客户端返回代表事务执行失败的空回复。
  • UNWATCH:命令将取消当前客户端对象的乐观锁key,该客户端对象的事务提交将变成无条件执行.
  • DISCARD:事务会被放弃, 事务队列会被清空, 并且客户端会从事务状态中退出

三、Redis 事务的三个阶段

1. 事务开始

MULTI 命令标志着事务的开始,通过将在客户端状态的flags属性中打开CLIENT_MULTI标识来完成从非事务状态切换至事务状态。
2. 命令入队
客户端发送exec、discard、watch、multi四个命令时,服务器立即执行。客户端发送的时除此4个命令之外的其他命令时,服务器将命令放入事务队列(FIFO),然后向客户端返回queued。
RedisServer RedisClient:
在这里插入图片描述
3. 事务执行
处于事务状态的客户端向服务器发送exec命令时,这个命令将被服务器立即执行。服务器首先会遍历这个客户端的事务队列,执行队列中保存的所有命令,最后将执行命令所得的结果全部返回客户端。

四、事务中的错误处理

  • 入队错误:如果一个事务在入队命令的过程中出现了命令不存在或格式不正确等情况,可以理解为编译时错误,比如说,命令可能会产生语法错误(参数数量错误,参数名错误,等等),或者其他更严重的错误,比如内存不足(如果服务器使用 maxmemory 设置了最大内存限制的话),返回ERR
  • 执行错误:执行命令过程中发生的错误都是一些不能在入队时被服务器发现的错误,可以理解为运行时错误,这些错误只会在 EXEC 调用之后命令错误失败

错误的处理:
入队错误在 Redis 2.6.5 以前, Redis 只执行事务中那些入队成功的命令,而忽略那些入队失败的命令。 Redis2.6.5 之后的版本,服务器会对命令入队失败的情况进行记录,并在客户端调用 EXEC 命令时,拒绝执行并自动放弃这个事务。 而新的处理方式则使得在流水线(pipeline)中包含事务变得简单,因为发送事务和读取事务的回复都只需要和服务器进行一次通讯。

执行错误,如果执行命令过程中发生了错误,服务器也不会中断事务的执行,它会继续执行事务中余下的命令,并且已执行的命令不会被出错的命令影响,也就是不会对失败之前成功执行的命令回滚失效。为什么不能像mysql事务那样全部成功?

为什么 Redis 不支持回滚(roll back)

  • 开发的作者认为:Redis命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令用在了错误类型的键上面:这也就是说,从实用性的角度来说,失败的命令是由开发人员的编程错误造成的,而这些错误应该在开发的测试过程中被发现和避免,而不应该出现在生产环境中。
  • 因为不需要对回滚这么复杂消耗性能的操作进行支持,这样带来的好处就是可以保持 Redis 的最突出的优点:简单且快速

五、Watch实现原理

每个Redis数据库都有一个watched_keys字典保存被监视的键,字典的key为被监视的键,字典的值
是一个链表,记录了所有监视相应数据库键的客户端。例如:现在有2台客服端监视了键 “name”,这时候为c10086的客服端执行 watch name,那么就会检测"name"是否已经存在了对应关系,如果没有,在后面添加c10086
在这里插入图片描述

在这里插入图片描述

  1. watched_keys字典监视的键被修改后,服务器会将服务器上保存的对应客户端信息中的标识为置为CLIENT_DIRTY_CAS。
  2. 服务端收到exec执行命令,如果当前客户端的标识位是CLIENT_DIRTY_CAS,则拒绝执行,否则提交事务
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值