订单抢购中常见的并发问题及解决
抢购遇到的并发问题
查询库存 当库存大于0的时候执行创建订单,减去库存数量等操作,但是在判断库存是否大于0时,并发问题,导致库存被减为负数
常见的较优的解决方案
非阻塞的文件排他锁
$fp = fopen('lock.txt','w+');
$lock_status = flock($fp,LOCK_EX|LOCK_NB); // 文件执行非阻塞锁定.
if(!$lock_status) { //当该文件被锁定时,无法再次被锁定
echo "网络繁忙,请稍后再试";
return;
}
// 执行库存查询,订单生产 库存减少等操作.
// 当时间执行结束以后,执行释放锁.
$unlock_status = flock($fp,LOCK_UN);
if ($unlock_status) {
echo "解锁成功";
}
fclose($fp);
redis队列,pop是原子性的, 即使很多用户同时到达,也是依次执行
// 1.现将库存全部排入队列中.
$store = 100; // 原定库存100
$store_key = "good_mq";
$redis = new Redis();
$redis->connect('127.0.0.1',6379);
$count = $store;
// 将库存添加到队列中.
if($count) {
for($i=0;$i<$count;$i++) {
$redis->rpush($store_key,1);
}
}
// 2. 检查库存 执行抢购.
// 检查是否还有库存
$is_has_good = $redis->rPop($store_key);
if (!$is_has_good) {
echo "已经被抢购完毕!";
}
// 执行抢购逻辑.
echo "抢购成功!存货:".$redis->llen($store_key);
网友评论