悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。
<?php
header('content-type:text/html;chaeset=utf-8'); /**
* redis实战
*
* 实现悲观锁机制
*
*/
$timeout = 5000;
$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);
do {
$microtime = microtime(true) * 1000;
$microtime_time = date('Y-m-d H:i:s',$microtime);
echo "执行microtime:{$microtime} ";
echo "执行microtime_time:{$microtime_time} ";
echo '<pre>';
$microtimeout = $microtime+$timeout+1;
$microtimeout_time = date('Y-m-d H:i:s',$microtimeout);
echo "执行microtimeout_time:{$microtimeout_time} ";
echo '<pre>';
// 上锁
$isLock = $redis->setnx('lock.count', $microtimeout);
if (!$isLock) {
$getTime = $redis->get('lock.count');
if ($getTime > $microtime) {
// 睡眠 降低抢锁频率 缓解redis压力
usleep(5000);
// 未超时继续等待
continue;
}
// 超时,抢锁,可能有几毫秒级时间差可忽略
$previousTime = $redis->getset('lock.count', $microtimeout);
if ((int)$previousTime < $microtime) {
break;
}
}
} while (!$isLock);
$count = $redis->get('count')? : 0;
// file_put_contents('/var/log/count.log.1', ($count+1));
// 业务逻辑
echo "执行count加1操作~ ";
echo '<pre>';
$redis->set('count', $count+1);
// 删除锁
$redis->del('lock.count');
// 打印count值
$count = $redis->get('count');
echo "count值为:$count ";
echo '<pre>';