php解决高并发(文件锁)
文件锁分为两种方式:
【一】.阻塞模式:(如果其他进程已经加锁文件,当前进程会一直等其他进程解锁文件后继续执行)
<?php //连接数据库 $con=mysqli_connect("192.168.2.186","root","root","test"); //查询商品数量是否大于0,大于0才能下单,并减少库存 $fp = fopen("lock.txt", "r"); //加锁 if(flock($fp,LOCK_EX)) { $res=mysqli_fetch_assoc(mysqli_query($con,'SELECT total FROM shop WHERE id=1 LIMIT 1')); if($res['total']>0){mysqli_query($con,'UPDATE shop SET total=total-1 WHERE id=1');} //执行完成解锁 flock($fp,LOCK_UN); } //关闭文件 fclose($fp); unset($res); mysqli_close($con); ?>
这种情况若是其他进程已经加锁文件,那么所有进程都会等他执行完并解锁文件后才会执行
【二】.非阻塞模式:(如果其他进程已经加锁文件,当前进程不会等其他进程解锁文件,而是走else)
<?php //连接数据库 $con=mysqli_connect("192.168.2.186","root","root","test"); //查询商品数量是否大于0,大于0才能下单,并减少库存 $fp = fopen("lock.txt", "r"); //加锁 if(flock($fp,LOCK_EX | LOCK_NB)) { $res=mysqli_fetch_assoc(mysqli_query($con,'SELECT total FROM shop WHERE id=1 LIMIT 1')); if($res['total']>0){mysqli_query($con,'UPDATE shop SET total=total-1 WHERE id=1');} //执行完成解锁 flock($fp,LOCK_UN); }else{
echo "locked file failed\n";
} unset($res); mysqli_close($con); ?>
这种情况就会直接走else返回提示信息