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

19 篇文章 0 订阅
15 篇文章 1 订阅
本文介绍了四种处理并发抢购场景的方法:1) 使用MySQL的行级锁机制确保数据一致性;2) 利用Redis的事务进行库存操作;3) 通过Redis队列实现公平的库存分配;4) 使用文件排他锁避免并发冲突。这些方法旨在保证库存管理的准确性和并发安全性。
摘要由CSDN通过智能技术生成

第一种方法:使用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);

}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值