redis05----Redis 中的事务

Redis支持简单的事务

Redismysql事务的对比

 

 

Mysql

Redis

开启

start transaction

multi

语句

普通sql

普通命令

失败

rollback 回滚

discard 取消(不叫回滚,是队列里面的命令不执行,队列里面的任务根本就没有执行。而不是执行了也可以撤回来)

成功

commit

exec

注: rollback与discard 的区别
如果已经成功执行了2条语句, 第3条语句出错.
Rollback后,前2条的语句影响消失.
Discard只是结束本次事务,前2条语句造成的影响仍然还在。严格来讲不叫回滚,只是叫取消。Redis的事务相对要简单。
r1:2>set wang 100
"OK"

r1:2>set zhao 100
"OK"

r1:2>multi
"OK"

r1:2>decrby zhao 100
"QUEUED"     //减100并没有执行,而是加入到了队列中,redis是单进程的,exec的时候就回去执行队列里面的语句

r1:2>incrby wang 100
"QUEUED"
r1:2>get wang
"QUEUED"

r1:2>get zhao
"QUEUED"
r1:2>exec 
注:
在mutil后面的语句中, 语句出错可能有2种情况
1: 语法就有问题, 
这种,exec时,报错, 所有语句得不到执行
r1:2>multi
"OK"

r1:2>decrby zhao 100
"QUEUED"

r1:2>sdsv 
"ERR unknown command 'sdsv'"

r1:2>exec
"EXECABORT Transaction discarded because of previous errors."   //事务取消了,zhao没有减100

2: 语法本身没错,但适用对象有问题. 比如 zadd 操作list对象
Exec之后,会执行正确的语句,并跳过有不适当的语句.
r1:2>multi
"OK"

r1:2>decrby zhao 100
"QUEUED"

r1:2>sadd wang pig    //wang是一个字符串,这里当成是集合在处理
"QUEUED"   //放在队列里面,命令尚没有执行,
r1:2>exec
1) "0"        //zhao的钱变为了0
2) "WRONGTYPE Operation against a key holding the wrong kind of value"     //第二个语句执行出错

(如果zadd操作list这种事怎么避免? 这一点,由程序员负责)
Multi是把命令放在一个队列里面,exec是真正的执行,语法错误则都不执行,语法没错但是适用对象有错则执行正确的语句跳过错误的语句。这就没法保证原子性。

r1:2>multi
"OK"

r1:2>decrby zhao 100
"QUEUED"

r1:2>decrby wang 100
"QUEUED"

r1:2>discard    //取消,就是清空队列,就不会执行了
"OK"
r1:2>mget zhao wang
1) "100"
2) "100"
思考: 
我正在买票
Ticket -1 , money -100
而票只有1张, 如果在我multi之后,和exec之前, 票被别人买了---即ticket变成0了.
我该如何观察这种情景,并不再提交

悲观的想法: 
世界充满危险,肯定有人和我抢, 给 ticket上锁, 只有我能操作. [悲观锁]

乐观的想法:
没有那么人和我抢,因此,我只需要注意,
--有没有人更改ticket的值就可以了 [乐观锁]

Redis的事务中,启用的是乐观锁,只负责监测key没有被改动.


具体的命令----  watch命令
例: 
redis 127.0.0.1:6379> watch ticket
OK
redis 127.0.0.1:6379> multi
OK
redis 127.0.0.1:6379> decr ticket
QUEUED
redis 127.0.0.1:6379> decrby money 100
QUEUED
//现在已经对ticket进行了监控,另外一个窗口将ticket改动了
另一个窗口:> decr ticket    
redis 127.0.0.1:6379> exec
(nil)   // 返回nil,说明监视的ticket已经改动了,事务就取消了.队列就不执行了。
redis 127.0.0.1:6379>mget ticket money
"0"
"200"

watch key1 key2  ... keyN
作用:监听key1 key2..keyN有没有变化,如果任意一个有变, 则事务取消
unwatch 
作用: 取消所有watch监听

 

posted @ 2018-01-12 17:14  无天666  阅读(275)  评论(0编辑  收藏  举报