Redis事务是什么
可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞,redis对事务有部分支持,没有强一致性
能干吗
一个队列中,一次性、顺序性、排他性的执行一系列命令。
常用命令
命令 | 描述 |
DISCARD | 取消事务,放弃执行事务块内的所有命令 |
EXEC | 执行所有事务块内的命令 |
MULTI | 标记一个事务块的开始 |
UNWATCH | 取消 WATCH 命令对所有 key 的监视 |
WATCH key [key …] | 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断 |
命令执行
1.正常执行:使用multi
+exec
组合
127.0.0.1:6379> keys * (empty array) 127.0.0.1:6379> multi OK 127.0.0.1:6379(TX)> set k1 v1 QUEUED 127.0.0.1:6379(TX)> set k2 v2 QUEUED 127.0.0.1:6379(TX)> exec 1) OK 2) OK
2.放弃命令:使用multi
+discard
组合
127.0.0.1:6379> multi OK 127.0.0.1:6379(TX)> set k3 v3 QUEUED 127.0.0.1:6379(TX)> set k4 v4 QUEUED 127.0.0.1:6379(TX)> discard OK 127.0.0.1:6379> keys * 1) "k2" 2) "k1"
3.一次错误全部不执行
127.0.0.1:6379> multi OK 127.0.0.1:6379(TX)> set k3 v3 QUEUED 127.0.0.1:6379(TX)> getset k3 (error) ERR wrong number of arguments for 'getset' command 127.0.0.1:6379(TX)> exec (error) EXECABORT Transaction discarded because of previous errors.
4.对错误的命令抛出异常,其他正常执行
127.0.0.1:6379> multi OK 127.0.0.1:6379(TX)> incr k1 QUEUED 127.0.0.1:6379(TX)> set k3 v3 QUEUED 127.0.0.1:6379(TX)> set k4 v4 QUEUED 127.0.0.1:6379(TX)> exec 1) (error) ERR value is not an integer or out of range 2) OK 3) OK
5.watch监控:一旦值发生修改就不会执行事务
127.0.0.1:6379> keys * (empty array) 127.0.0.1:6379> set balance 200 OK 127.0.0.1:6379> set debt 0 OK 127.0.0.1:6379> watch balance OK 127.0.0.1:6379> multi OK 127.0.0.1:6379(TX)> set balance 80 QUEUED 127.0.0.1:6379(TX)> exec (nil)
Unwatch
命令用于取消 WATCH 命令对所有 key 的监视
总结
- Watch指令,类似乐观锁,事务提交时,如果Key的值已被别的客户端改变, 比如某个list已被别的客户端push/pop过了,整个事务队列都不会被执行
- 通过WATCH命令在事务执行之前监控了多个Keys,倘若在WATCH之后有任何Key的值发生了变化, EXEC命令执行的事务都将被放弃,同时返回Nullmulti-bulk应答以通知调用者事务执行失败