1. 什么是事务?
Redis 的事务和 MySQL的事务概念上是类似的,都是把一系列操作绑定成一组.让这一组能够批量执行.但是注意体会 Redis 的事务和 MySQL 事务的区别:
- 弱化的原子性: redis 没有"回滚机制".只能做到这些操作"批量执行",
不能做到"一个失败就恢复到初始状态".
- 不保证一致性:不涉及"约束”也没有回滚.MySOL的一致性体现的是运行事务前和运行后,结果都是合理有效的,不会出现中间非法状态.
- 不需要隔离性:也没有隔离级别,因为不会并发执行事务(redis 单线程处理请求)
- 不需要持久性:是保存在内存的,是否开启持久化,是redis-server 自己的事情,和事务无关.
Redis 事务本质上是在服务器上搞了一个"事务队列",每次客户端在事务中进行一个操作,都会把命令先发给服务器,放到"事务队列"中(但是并不会立即执行)而是会在真正收到 EXEC命令之后,才真正执行队列中的所有操作.
整体来说,Redis的事务的功能相对于MySQL来说是弱很多的,只能够保证事务中的这几个操作时“连续的”,不会被其他的客户端加塞,仅此而已。
2. 事务操作
- MULTI:标记事务的开始,成功开启事务后,返回OK。
- EXEC:执行事务中的所有命令。
- DISCARD:取消事务,放弃事务中的所有命令。
- WATCH:监视一个或多个键,如果在执行事务之前这些键被其他命令修改,则事务会被取消。
2.1 MULTI、EXEC、DISCARD
开启一个事务,执行成功返回OK。开启事务后redis命令就会被放到FIFO队列中,接收到EXEC命令后就会打包执行队列中的命令。
EXEC就是真正的去执行事务,执行队列中的命令。
每次添加一个操作,都会提示"QUEUED",说明命令已经进入客户端的队列了真正执行 EXEC 的时候,客户端才会真正把上述操作发送给服务器.此时就可以获取到上述 key 的值了.
DISCARD 就是放弃当前事务,此时就会讲队列中的事务清空,之前的所有操作都不会真正被执行。
2.2 WATCH
如果我们在执行事务的过程中,某个事物中修改的值,又被其他的客户端修改了,此时就会容易出现数据不一致问题。
WATCH命令就能够监控key,在上面的场景中,通过WATCH可以看key在事务的MULTI和EXEC之间,set key之后,是否被外部其他的客户端修改。
watch 命令就是用来解决这个问题的.watch 在该客户端上监控一组具体的 key.
- 当开启事务的时候,如果对 watch 的 key进行修改,就会记录当前 key 的"版本号".(版本号是个简单的整数,每次修改都会使版本变大.服务器来维护每个 key 的版本号情况)
- 在真正提交事务的时候,如果发现当前服务器上的 key的版本号已经超过了事务开始时的版本号,就会让事务执行失败.(事务中的所有操作都不执行).
与之对应的还有UNWATCH,取消对 key 的监控.相当于 WATCH 的逆操作.