Redis事务

Redis支持事务机制,但mysql事务机制不同的是,redis的事务没有回滚这一说法
Redis的事务本质上是一组命令的集合,即一次执行多个命令:
- 事物中的命令按顺序执行,执行过程中,其他客户端的命令不会插入进来
- 事物中的命令要么执行,要么不执行,即使事务中有些命令执行失败,后续命令不会受其影响继续执行。
Redis提供MULTI、EXEC、DISCARD、WATCH命令来实现事物功能。
MULTI命令开启一个事物,后续命令可放入事物队列命令
EXEC命令执行事务命令队列中所有命令
DISCARD命令抛弃事务命令队列中的命令
WATCH命令监视指定键,当后续事务执行前发现这些健已经修改,则拒绝执行事务,因此watch常用于乐观锁
- watch命令原理:
- 在redis中有个watched_keys的字典,字典的健里面放的是被监视的redis健,值则是监视字典的所有客户端列表。
- 当健受到修改的时候,其对应的客户端列表会被添加CLIENT_DIRTY_CAS标志,代表客户端监视的健已经被修改
- multi、exec命令执行流程
- 检查客户端是否开启事务,若开启则将命令放入客户端事务队列中。
- 当客户端监视的健已经被修改或客户端拒绝事务中的命令,则直接抛弃事务命令队列中的命令,并进行错误处理
- 当服务器处于异常状态,拒绝执行命令
- 取消当前客户端对所有健的监视,watch只能作用于后续事务
- 执行事务的第一个写命令执行,传播MULTI命令到AOF文件和从节点
- 检查用户ACL权限,通过则执行命令
- 执行完所有命令后,重置客户端上下文,删除标志
- 如果事务中执行了写命令,修改server.dirty属性,将EXEC命令传播到AOF文件和从节点,从而保证一个事务的MULTI、EXEC命令都被传播。
