可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞。
1. Redis事务与数据库事务对比
- 单独的隔离操作:Redis的事务仅仅是保证事务里的操作会被连续独占的执行,redis命令执行是单线程架构,在执行完事务内所有指令前是不可能再去同时执行其他客户端的请求的
- 没有隔离级别的概念:因为事务提交前任何指令都不会被实际执行,也就不存在”事务内的查询要看到事务里的更新,在事务外查询不能看到”这种问题了
- 不保证原子性:Redis的事务不保证原子性,也就是不保证所有指令同时成功或同时失败,只有决定是否开始执行全部指令的能力,没有执行到一半进行回滚的能力
- 排它性:Redis会保证一个事务内的命令依次执行,而不会被其它命令插入
2. Redis事务命令
MULTI 标记一个事务块的开始
DISCARD 取消事务,放弃执行事务块内的所有命令
EXEC 执行所有事物块内的命令
UNWATCH 取消WATCH命令对所有key的监视
WATCH key [key ...]
监视一个或多个key,如果在事务执行之前这个
或这些key被其它命令所改动,那么事务将会被打断
2.1 正常执行
一个事务中的命令会被放入一个队列中,执行EXEC后一次性、排他地顺序执行事务块内的命令。
2.2 放弃执行
使用DISCARD,事务块内的命令不会被执行。
2.3 全部失败
一条命令可能无法加入队列,即在EXEC前产生错误,此时事务块内的命令全部失败(类似于编译时错误)。
2.4 部分失败
在EXEC后产生错误,产生错误的命令执行失败,但其它命令可以正常执行(类似于运行时错误)。
注:Redis不提供事务回滚功能,因此在事务出错后需自行恢复数据库状态。
2.5 watch监控
Redis使用watch来提供乐观锁定,类似于CAS(Check-and-Set)。
如图,在exec之前,被watch的tk1在另一个客户端中发生改变,此时exec后事务中的命令全部不执行。
注:一旦执行了exec,之前加的监控锁都会被取消;当客户端丢失连接的时候,所有东西都会被取消监视(也就是说在一个客户端中被监控的key,在另一个客户端中不生效)