Redis 事务
Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:
- 批量操作在发送 EXEC 命令前被放入队列缓存。
- 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
- 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。
127.0.0.1:6379> multi #事务以multi为开始,开启一个事务
OK
127.0.0.1:6379> set k1 v1 #以实际的redis命令为中间阶段
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> get k2
QUEUED
127.0.0.1:6379> get k3
QUEUED
127.0.0.1:6379> exec #以exec执行为结束阶段;
1) OK
2) OK
3) OK
4) "v2"
5) "v3"
单个 Redis 命令的执行是原子性的!
但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。
事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。
运行时异常:中途错误命令不会影响后续命令的执行。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> multi #开启事务
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> incr k1 #中间阶段有一步报错
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> exec # 执行后发现;报错不会妨碍k3值的写入
1) OK
2) OK
3) (error) ERR value is not an integer or out of range
4) OK
127.0.0.1:6379> mget k1 k2 k3
1) "v1"
2) "v2"
3) "v3"
编译性异常:中途出现错误,后续操作不被执行
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> getset k2
(error) ERR wrong number of arguments for 'getset' command
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> set k4 v4
QUEUED
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
discard取消事务
discard 命令用于取消事务,放弃执行事务块内的所有命令。
127.0.0.1:6379> multi
OK
127.0.0.1:6379> get key1
QUEUED
127.0.0.1:6379> set k2
(error) ERR wrong number of arguments for 'set' command
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> discard
OK
127.0.0.1:6379> exec
(error) ERR EXEC without MULTI
watch
watch 命令用于监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
正常情况:
127.0.0.1:6379> set money 100 #设置钱包100元
OK
127.0.0.1:6379> set out 0 #设置支出0元
OK
127.0.0.1:6379> watch money #监视钱包
OK
127.0.0.1:6379> multi #开启事务
OK
127.0.0.1:6379> decrby money 20
QUEUED
127.0.0.1:6379> incrby out 20
QUEUED
127.0.0.1:6379> exec #执行事务
1) (integer) 80
2) (integer) 20
异常情况:
客户端1:
127.0.0.1:6379> mget money out #1 查看当前钱包余额 & 支出月
1) "80"
2) "20"
127.0.0.1:6379> watch money #2 监视当前钱包余额
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby money 10
QUEUED
127.0.0.1:6379> incrby out 10 #先不执行,去客户端2执行命令
QUEUED
127.0.0.1:6379> exec # 4 执行事务
(nil) #返回nil 执行失败!
客户端2:
root@AY140210092026Z:~# redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> incrby money 100 #3 改变钱包余额充值100元
(integer) 180
unwatch
unwatch 命令用于取消 WATCH 命令对所有 key 的监视。
127.0.0.1:6379> unwatch
OK
本文由 huzd 创作,采用 知识共享署名4.0 国际许可协议进行许可本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名最后编辑时间
为:
2021/02/18 09:21