Redis 乐观锁

乐观锁大多是以数据版本号来进行成功或者失败!

举个例子:

假设某个文章的点赞数为100,此时的version我们暂定没有异常为100.

当用户A对他进行点赞的时候进行操作,那此时的点赞数为100+1、version=101,提交更新时,由于版本号大于数据库记录的版本号,数据被更新,此时数据记录的version=101。

然而在特殊情况下用户B是和用户A是同时进行操作的,也就是说,他获得的version也是100、点赞数为100,提交结果是点赞数为100+1、version=101,但是此时对数据库的版本发现当前数据记录的version也为101,不满足当前提交版本号大于数据库版本号,所以此时更新操作被驳回。

执行实验代码:

WATCH test

value = GET test

value = value+1

MULTI

SET test value

EXEC

由于WATCH 的key会被监视,会校验这个key是否被更改,如果该监视的key 在EXEC执行前被修改了,那么整个事务都会被驳回。

php实现代码

$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
//获取当前点赞数 
$test = $redis->get("test");  
$count = 1;   //默认每次点赞+1  

$redis->watch("test");  
$redis->multi();  
//设置延迟,方便测试效果。  
sleep(5);  
//插入抢购数据  
$redis->set("test",$test+$count);  
$res = $redis->exec();  
if($res){  
    $new_test = $redis->get("test");  
    echo "点赞成功当前点赞数为:".$new_test."<br/>";  
}else{  
    echo "点赞失败";exit;  
}  

需要注意的是如果使用同一个浏览器的多个标签页同时访问同一个URL,那么浏览器认为这些不同的请求是同一个人,会对你的每个请求进行排队,不做并发处理。不管Nginx还是Apache,都是在并发处理,只不过你的浏览器自作主张,把你的请求阻塞了。

标签:Redis 发布于:2019-11-07 06:51:50