[摘要]LOCK_NB)){echo "系统繁忙,请稍后再试";return;}//下单$sql="select number from ih_store where good...
LOCK_NB)){
echo "系统繁忙,请稍后再试";
return;
}
//下单
$sql="select number from ih_store where goods_id='$goods_id' and sku_id='$sku_id'";
$rs = mysqli_query($conn,$sql);
$row = $rs->fetch_assoc();
if($row['number']>0){//库存是否大于0
//模拟下单操作
$order_sn=build_order_no();
$sql="insert into ih_order(order_sn,user_id,goods_id,sku_id,price)
values('$order_sn','$user_id','$goods_id','$sku_id','$price')";
$order_rs = mysqli_query($conn,$sql);
//库存减少
$sql="update ih_store set number=number-{$number} where sku_id='$sku_id'";
$store_rs = mysqli_query($conn,$sql);
if($store_rs){
echo '库存减少成功';
insertLog('库存减少成功');
flock($fp,LOCK_UN);//释放锁
}else{
echo '库存减少失败';
insertLog('库存减少失败');
}
}else{
echo '库存不够';
insertLog('库存不够');
}
fclose($fp);
?>
5. 乐观锁思路
这个时候,我们就可以讨论一下“乐观锁”的思路了。乐观锁,是相对于“悲观锁”采用更为宽松的加锁机制,大都是采用带版本号(Version)更新。实现就是,这个数据所有请求都有资格去修改,但会获得一个该数据的版本号,只有版本号符合的才能更新成功,其他的返回抢购失败。这样的话,我们就不需要考虑队列的问题,不过,它会增大CPU的计算开销。但是,综合来说,这是一个比较好的解决方案。

有很多软件和服务都“乐观锁”功能的支持,例如Redis中的watch就是其中之一。通过这个实现,我们保证了数据的安全。
优化方案5:Redis中的watch
<?php
$redis = new redis();
$result = $redis->connect('127.0.0.1', 6379);
echo $mywatchkey = $redis->get("mywatchkey");
/*
//插入抢购数据
if($mywatchkey>0)
{
$redis->watch("mywatchkey");
//启动一个新的事务。
$redis->multi();
$redis->set("mywatchkey",$mywatchkey-1);
$result = $redis->exec();
if($result) {
$redis->hSet("watchkeylist","user_".mt_rand(1,99999),time());
$watchkeylist = $redis->hGetAll("watchkeylist");
echo "抢购成功!<br/>";
$re = $mywatchkey - 1;
echo "剩余数量:".$re."<br/>";
echo "用户列表:<pre>";
print_r($watchkeylist);
}else{
echo "手气不好,再抢购!";exit;
}
}else{
// $redis->hSet("watchkeylist","user_".mt_rand(1,99999),"12");
// $watchkeylist = $redis->hGetAll("watchkeylist");
echo "fail!<br/>";
echo ".no result<br/>";
echo "用户列表:<pre>";
// var_dump($watchkeylist);
}*/
$rob_total = 100; //抢购数量
if($mywatchkey<=$rob_total){
$redis->watch("mywatchkey");
$redis->multi(); //在当前连接上启动一个新的事务。
//插入抢购数据
$redis->set("mywatchkey",$mywatchkey+1);
$rob_result = $redis->exec();
if($rob_result){
$redis->hSet("watchkeylist","user_".mt_rand(1, 9999),$mywatchkey);
$mywatchlist = $redis->hGetAll("watchkeylist");
echo "抢购成功!<br/>";
echo "剩余数量:".($rob_total-$mywatchkey-1)."<br/>";
echo "用户列表:<pre>";
var_dump($mywatchlist);
}else{
$redis->hSet("watchkeylist","user_".mt_rand(1, 9999),'meiqiangdao');
echo "手气不好,再抢购!";exit;
}
}
?>以上就是解析秒杀抢购思路以及高并发下数据安全的详细内容,更多请关注php中文网其它相关文章!
学习教程快速掌握从入门到精通的SQL知识。
关键词:解析秒杀抢购思路以及高并发下数据安全