乐观锁大多是以数据版本号来进行成功或者失败!
举个例子:
假设某个文章的点赞数为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,都是在并发处理,只不过你的浏览器自作主张,把你的请求阻塞了。