Redis 事务
- redis 事务
- 事务操作
- multi 开启事务
- exec 执行事务
- discard 放弃当前事务
- watch
- unwatch
redis 事务
Redis 的事务和 MySQL 的事务概念上是类似的。 都是把⼀系列操作绑定成⼀组。 让这⼀组能够批量执⾏。
Redis 的事务和 MySQL 事务的区别:
- 弱化的原⼦性: 这里指的是 redis 能够做到把多个操作打包到一起,要么全部执行,要么全都不执行,但是不保证事务执行后一定是成功,事务执行失败后,失败就失败,不进行回滚操作。所以以 mysql的事务的原子性来说,redis可以说是没有原子性。
- 不具备⼀致性: 不涉及 “约束”。也没有回滚。 MySQL 的⼀致性体现的是运⾏事务前和运⾏后, 结果都是合理有效的, 不会出现中间⾮法状态。
- 不涉及隔离性: redis 是一个单线程模型的服务器程序,所有的 请求/事务,都是”串行“执行的,也没有隔离级别, 因为不会并发执⾏事务 (redis 单线程处理请求) 。
- 不具备持久性: 数据是保存在内存的。是否开启持久化, 是 redis-server ⾃⼰的事情, 和事务⽆关。
Redis 事务本质上是在服务器上搞了⼀个 “事务队列”。
开启事务的时候,此时客户端输入的命令,就会发给服务器并且进入这个队列中(而不是立即执行)。当遇到了”执行事务“命令的时候,此时就会把队列中的这些任务都按顺序一次执行。(这些都是在 redis 主线程中完成的)
事务操作
multi 开启事务
作用:开启⼀个事务. 执⾏成功返回 OK.
每次添加⼀个操作,都会提⽰ QUEUED", 说命令已经进⼊客户端的队列了
exec 执行事务
作用:真正执⾏事务.
discard 放弃当前事务
当开启事务,并且给服务器发送了若干个命令之后,此时服务器重启,此时的这个事务该怎么办呢?
此时的效果其实就等同于 discard命令。
watch
作用:在执⾏事务的时候, 如果某个事务中修改的值, 被别的客户端修改了, 此时就容易出现数据不⼀致的问题。
在开启事务之前执行watch
如下图所示:
假设此时有一个 key,value 为 111,此时有两个客户端,客户端1先开启一个事务,并将key的value设置为222,此时客户端2不开启事务直接set key 333,此时客户端1执行exec命令,让其执行事务,此时就容易引起歧义,是到底key的值是222还是333呢。其实是222。
watch 命令就是⽤来解决上述这个问题的。watch 在该客户端上监控⼀组具体的 key.
- 当开启事务的时候, 如果对 watch 的 key 进⾏修改, 就会记录当前 key 的 “版本号”. (版本号是个简单的整数, 每次修改都会使版本变⼤. 服务器来维护每个 key 的版本号情况)
- 在真正提交事务的时候, 如果发现当前服务器上的 key 的版本号已经超过了事务开始时的版本号, 就会让事务执⾏失败. (事务中的所有操作都不执⾏).
unwatch
取消对 key 的监控。