1 🍑事务概念🍑

Redis 的事务和 MySQL 的事务概念上是类似的,都是把⼀系列操作绑定成⼀组,让这⼀组能够批量执⾏。
但是注意体会 Redis 的事务和 MySQL 事务的区别:

  • 弱化的原⼦性: redis 没有 “回滚机制”. 只能做到这些操作 “批量执⾏”,不能做到 “⼀个失败就恢复到初始状态”。
  • 不保证⼀致性: 不涉及 “约束”,也没有回滚,MySQL 的⼀致性体现的是运⾏事务前和运⾏后 , 结果都是合理有效的, 不会出现中间⾮法状态。
  • 不需要隔离性: 也没有隔离级别,因为不会并发执⾏事务 (redis 单线程处理请求) 。
  • 不需要持久性: 是保存在内存的,是否开启持久化是redis-server⾃⼰的事情,和事务⽆关。

Redis 事务本质上是在服务器上搞了⼀个 “事务队列”,每次客⼾端在事务中进⾏⼀个操作都会把命令先发给服务器, 放到 “事务队列” 中(但是并不会⽴即执⾏),⽽是会在真正收到 EXEC 命令之后, 才真正执⾏队列中的所有操作。
因此, Redis 的事务的功能相⽐于 MySQL 来说, 是弱化很多的. 只能保证事务中的这⼏个操作是 “连续的”, 不会被别的客⼾端 “加塞”, 仅此⽽已。


2 🍑事务操作🍑

2.1 🍎multi🍎

开启⼀个事务. 执⾏成功返回 OK。
实例:
【Redis:事务】-LMLPHP

2.2 🍎exec🍎

真正执⾏事务。
实例:
【Redis:事务】-LMLPHP
每次添加⼀个操作, 都会提⽰ “QUEUED”, 说明命令已经进⼊客⼾端的队列了,真正执⾏ EXEC 的时候, 客⼾端才会真正把上述操作发送给服务器。

2.3 🍎discard🍎

放弃当前事务,此时直接清空事务队列,之前的操作都不会真正执⾏到。
实例:
【Redis:事务】-LMLPHP

2.4 🍎watch🍎

监控⼀组具体的 key。
实例:我们开两个客户端,客户端1和客户端2。
在客户端1上执行:
【Redis:事务】-LMLPHP
客户端1只是⼊队列, 但是不提交事务执⾏。
在客户端2上执行:
【Redis:事务】-LMLPHP
此时客户端1再真正执行事务:
【Redis:事务】-LMLPHP
此时说明事务已经被取消了,这次提交的所有命令都没有执⾏。

那么watch的实现原理是什么呢?
其实watch是类似于版本号的方式来实现的一种“乐观锁”。
就拿上面的例子来说,刚开始客户端k1的版本号为0(这个数字是假设的),当客户端2修改k1后此时在服务器端就会修改k1的版本号为1,当客户端执行exec后就会发现此时k1的版本号与最初的不一致,便舍弃该事务。

2.5 🍎unwatch🍎

取消对 key 的监控,相当于 WATCH 的逆操作。


03-01 06:40