12-Redis - 事务

案例1:事务的简单操作

127.0.0.1:6379> keys *
(empty list or set)
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> get k2
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) OK
3) "v2"
4) OK
127.0.0.1:6379> 

 放弃执行命令

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set k1 11
QUEUED
127.0.0.1:6379> set k2 22
QUEUED
127.0.0.1:6379> set k3 33
QUEUED
127.0.0.1:6379> DISCARD
OK
127.0.0.1:6379> get k2
"v2"
127.0.0.1:6379> 

(1)在一个事务中,只要有一条命令是错误的,那么整个事务就执行失败,由于事务的原子性,数据自动恢复到事务执行之前的状态

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set k1 11
QUEUED
127.0.0.1:6379> set k2 22
QUEUED
127.0.0.1:6379> getset k3
(error) ERR wrong number of arguments for 'getset' command
127.0.0.1:6379> set k4 44
QUEUED
127.0.0.1:6379> set k5 55
QUEUED
127.0.0.1:6379> EXEC
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get k5
(nil)
127.0.0.1:6379> 

 (2)下面的事务中,有一条命令是错误的,但是这个事务中的其他命令照样执行,指示不执行错误的那条命令

127.0.0.1:6379> keys *
1) "k2"
2) "k3"
3) "k1"
127.0.0.1:6379> get k1
"11"
127.0.0.1:6379> get k2
"v2"
127.0.0.1:6379> get k3
"v3"
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> INCR k1
QUEUED
127.0.0.1:6379> INCR k2
QUEUED
127.0.0.1:6379> set k4 v4
QUEUED
127.0.0.1:6379> set k5 v5
QUEUED
127.0.0.1:6379> EXEC
1) (integer) 12
2) (error) ERR value is not an integer or out of range
3) OK
4) OK
127.0.0.1:6379> get k1
"12"
127.0.0.1:6379> get k2
"v2"
127.0.0.1:6379> get k3
"v3"
127.0.0.1:6379> get k4
"v4"
127.0.0.1:6379> get k5
"v5"
127.0.0.1:6379> 

总结以上的(1)和(2),(1)中是命令在事务之中就报错了(相当于Java中编译时就报错了),(2)中是命令在事务之中没报错,在执行的时候报错(相当于Java中的执行时报错),但是(1)中的事务中的所有命令都不执行,而(2)中的事务中的命令只是错误的没执行,正确的命令却照样执行。所以Redis对事务的支持的结论是:

Redis部分执行事务

1. 当在入队时发生错误时就支持事务的原子性(支持事务,所有命令要么一起成功,要么一起失败)

2. 当在入队时不发生错误,但是在执行的时候发生错误,这时候Redis就不支持事务(不支持事务的原子性,正确的命令允许执行,错误的命令阻止执行)

事务案例1:模拟余额和欠债

(1)开始余额100元,欠债0元,花了20元,余额变80,欠债20

(2)第二次监听balance。(1)中的事务完成后,又继续监听balance(左边),而监听完了之后,在右边(模拟另外一个人),有人给余额充值200元

左边的这个人又花了20,欠债增加20,结果是nil(执行不成功)

接着左边那哥们儿查了下余额balance,发现余额变成了280(因为余额100,第一次花了20,余额变成了80,但是在第二次花销之前,有人给他充值了200,所以余额280)

这时候欠债还是20

 

在事务的中间发现数据修改之后,使用watch命令监听到事务被中途更改之后立即unwatch,然后重新watch之后,再继续接下来的修改操作就不会报错

注意:unwatch命令是针对所有key进行监视

 

posted @ 2017-08-10 15:58  半生戎马,共话桑麻、  阅读(145)  评论(0)    收藏  举报
levels of contents