客户端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可以同时监控多个键,在监控期间只要有一个键被其它客户端改变,则整个事务回滚。 |
| | |