php 处理库存超卖的几种处理方法

有目标就不怕路远。年轻人.无论你现在身在何方.重要的是你将要向何处去。只有明确的目标才能助你成功。没有目标的航船.任何方向的风对他来说都是逆风。因此,再遥远的旅程,只要有目标.就不怕路远。没有目标,哪来的劲头?一车尔尼雷夫斯基

导读:本篇文章讲解 php 处理库存超卖的几种处理方法,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

第一种方法:使用mysql数据库的锁机制。在事务中使用  for update 语句,在事务处理完成之后释放这一条数据。

代码使用tp5的框架:

public function mysqlLock(){
$goods_id = 26545;

$sku_id = 26545;

$price = 300;

$user = '';

StoreOrderModel::startTrans();

$nums = StoreOrderModel::where(['id'=>1])->field('number')->lock(true)->find();

$nums = $nums['number'];

if($nums > 0){
$item['goods_id'] = $goods_id;

$item['sku_id'] = $sku_id;

$item['number'] = $nums;

$item['price'] = $price;

$item['user'] = $user;

$id = StoreModel::insertGetId($item);

if($id){
StoreOrderModel::where(['id'=>1])->setDec('number');

StoreOrderModel::commit();

}else{
StoreOrderModel::rollback();

}

}else{
echo "没有库存了";

}

}

第二种方法:redis 事务。

public function start_reids_tran(){
$goods_id = 26545;

$sku_id = 26545;

//$number = 1;

$price = 300;

$user = '';

$redis = ResRedisModel::getinstance();

$redis->watch('store');

$nums = intval($redis->get('store'));

if($nums > 0){
$item['goods_id'] = $goods_id;

$item['sku_id'] = $sku_id;

$item['number'] = $nums;

$item['price'] = $price;

$item['user'] = $user;

$redis->lPush('success', json_encode($item));

$redis->multi();

$redis->decr('store');

$replies = $redis->exec(); // 执行以上 redis 事务

if(!$replies){
echo "订单 {$nums} 回滚".PHP_EOL;

}

$redis->unwatch();

echo "抢购成功!".PHP_EOL;

}else{
echo "没有库存了";

}

}

第三种方法:redis 队列,预先把库存信息存入队列当中,抢购时判断队列的数量,然后出队。队列为空时库存为0。

public function eq_start(){
$redis = ResRedisModel::getinstance();

$nums = $redis->lSize('store');

$goods_id = 26545;

$sku_id = 26545;

$number = 1;

$price = 300;

$user = '';

if($nums > 0){
$user = $redis->rPop('store');

if($user){
$item['goods_id'] = $goods_id;

$item['sku_id'] = $sku_id;

$item['number'] = $number;

$item['price'] = $price;

$item['user'] = $user;

StoreModel::insertGetId($item);

echo '抢购成功!';

}else{
echo '抢购失败!';

}

}else{
echo '抢购失败!';

}

}

第四种,文件排他锁方式

public function file_star(){
$fp = fopen('D:/phpStudy/PHPTutorial/www/public/lock.txt', "r");

if(flock($fp, LOCK_EX)) { //排他型锁定 阻塞模式 , flock($fp,LOCK_EX | LOCK_NB) 非阻塞模式

$nums = StoreOrderModel::where(['id'=>1])->field('number')->find();

$nums = $nums['number'];

if($nums > 0){
$goods_id = 26545;

$sku_id = 26545;

$number = 1;

$price = 300;

$user = '213';

$item['goods_id'] = $goods_id;

$item['sku_id'] = $sku_id;

$item['number'] = $number;

$item['price'] = $price;

$item['user'] = $user;

StoreModel::insertGetId($item);

StoreOrderModel::where(['id'=>1])->setDec('number');

flock($fp, LOCK_UN); //释放锁定

echo '抢购成功!';

}else{
echo '没有库存了!';

}

}else{
echo '抢购失败!';

}

fclose($fp);

}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/134003.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!