Redis-Transactions(事物)
你问我Redis支不支持事物?告诉你,Redis对事物的支持是部分支持(对比关系型数据库,没有强一致性)
定义:一个队列、一次性、顺序的、排他性的执行一系列命令
常用命令:
DISCARD 取消事物,放弃执行事物块内的所有命令
EXEC 执行事物块内的所有命令
MULTI 标记一个事物块的开始
UNWATCH 取消watch命令对所有key的监控
WATCH 监控一个或多个key,如果在事物执行之前,key被其他命令改动,那么事物将被打断
Case1:正常执行
Case2:放弃事物
我们可以发现,k1还是Case1中设置的值
Case3:全体连坐(一个捣蛋,全体都死)
Case4:冤头债主(错误的不执行,正确的照常执行)
k1位字符型,增加1显然不行,但是语法没错(加入了队列,不像Case3中的直接报错)。执行EXEC时,出现错误的语句块不会执行成功,但不影响事物块中其他的命令执行
Case5:watch监控
⑴ 第一步:(balance 可用余额,debt:欠款),假设我买了个包子20块刷了我的信用卡,可用余额减20,欠款加20
⑵ 第二步(当第一个窗口watch[监控]balance的后,在第二个窗口将balance设置成了1000块,然后我在第一个窗口又买了个包子花了20块,执行事物发现,并没有成功,获得最新的balance为1000):
上面这部类似于数据库中的乐观锁,当我们修改一条记录的时候,别人也在试图修改这条记录,当别人先于我之前就提交了,那么我提交的时候,就不能覆盖别人提交的数据,所以rollback了。
⑶ 第三步(第一个窗口watch[监控]我的余额后,在第二个窗口修改余额,假设此时我知道有人改了我的余额,那我在第一个窗口Unwatch一下,然后再watch下,设置我的余额为100,欠款为0,执行成功):
小结:WATCH监控一个或多个key,如果在事物执行之前,key被其他命令改动,那么事物将被打断(事物队列都不会被执行)
一旦执行了exec,之前加的监控锁都会被取消
如果是watch多个key,倘若watch之后有人改动过其中的key,exec执行的事物将都被放弃,同时返回NullMulti-bulk应答以通知调用者事物执行失败