redis的高级事务CAS(乐观锁)

Optimistic locking using check-and-set(乐观锁)

乐观锁介绍:
watch指令在redis事物中提供了CAS的行为。为了检测被watch的keys在是否有多个clients同时改变引发冲突,这些keys将会被监控。若是至少有一个被监控的key在执行exec命令前被修改,整个事物将会回滚,不执行任何动做,从而保证原子性操做,而且执行exec会获得null的回复。redis

乐观锁工做机制:
watch 命令会监视给定的每个key,当exec时若是监视的任一个key自从调用watch后发生过变化,则整个事务会回滚,不执行任何动做。注意watch的key是对整个链接有效的,事务也同样。若是链接断开,监视和事务都会被自动清除。固然exec,discard,unwatch命令,及客户端链接关闭都会清除链接中的全部监视。还有,若是watch一个不稳定(有生命周期)的key而且此key天然过时,exec仍然会执行事务队列的指令。数据库

客户端1 客户端2 说明
redis 127.0.0.1:6379> get age
"10"
redis 127.0.0.1:6379> get name
"zhangsan"
 
redis 127.0.0.1:6379> get age
"10"
redis 127.0.0.1:6379> get name
"zhangsan"
数据库中两客户端登陆,及键初始值。
redis 127.0.0.1:6379> multi
OK
redis 127.0.0.1:6379> incr age
QUEUED
redis 127.0.0.1:6379> set name lisi
QUEUED
  此时,客户端1开启事务,并提交队列命令:
1.想要将当前age自增+1运算;
2.将name值改成lisi
  redis 127.0.0.1:6379> incr age
(integer) 11

 
此时,客户端2修改了age值

redis 127.0.0.1:6379> exec
1) (integer) 12
2) OK

redis 127.0.0.1:6379> get name
"lisi"
  此时,客户端1执行队列命令,发现运算以后age不是理想中的11,而是12缘由是被其它客户插足抢先给修改了。name值也修改了。这样可能致使数据不一致性...

为了解决这个问题引入“乐观锁”的机制:
     
     
客户端1-引入“乐观锁”机制 客户端2 说明
redis 127.0.0.1:6379> get age
"10"
redis 127.0.0.1:6379> get name
"zhangsan"
 
redis 127.0.0.1:6379> get age
"10"
redis 127.0.0.1:6379> get name
"zhangsan"
数据库中两客户端登陆,及键初始值。
redis 127.0.0.1:6379> watch age name
OK
redis 127.0.0.1:6379> multi
OK
redis 127.0.0.1:6379> incr age
QUEUED
redis 127.0.0.1:6379> set name lisi
QUEUED
  此时,客户端1用watch命令监视age和name,而后开启事务,并提交队列命令
  redis 127.0.0.1:6379> incr age
(integer) 11
 
此时,客户端2修改了age值

redis 127.0.0.1:6379> exec
(nil)
redis 127.0.0.1:6379> get age
"11"
redis 127.0.0.1:6379> get name
"zhangsan"
  此时,客户端1执行队列命令,由watch监控发现此期间age的值已经被修改过,则让事整个务回滚,不作任何动做。 watch能够同时监控多个键,在监控期间只要有一个键被其它客户端改变,则整个事务回滚。
相关文章
相关标签/搜索