日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

项目秒杀思路(转)

發(fā)布時(shí)間:2025/3/15 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 项目秒杀思路(转) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在做一個(gè)團(tuán)購(gòu)項(xiàng)目,遇到個(gè)問(wèn)題,就是在搶購(gòu)、秒殺、抽獎(jiǎng)等活動(dòng)時(shí),庫(kù)存數(shù)量有限,但是同時(shí)下單人數(shù)超過(guò)了庫(kù)存數(shù)量,就會(huì)導(dǎo)致商品超售問(wèn)題。那么我們?cè)趺磥?lái)解決這個(gè)問(wèn)題呢,我的思路如下:?

sql1:查詢(xún)商品庫(kù)存
if(庫(kù)存數(shù)量 > 0)
{
? //生成訂單...
? sql2:庫(kù)存-1
}

當(dāng)沒(méi)有并發(fā)時(shí),上面的流程看起來(lái)是如此完美,假設(shè)同時(shí)兩個(gè)人下單,而庫(kù)存只有1個(gè)了,在sql1階段兩個(gè)人查詢(xún)到的庫(kù)存都是>0的,于是最終都執(zhí)行了sql2,庫(kù)存最后變?yōu)?1,超售了,要么補(bǔ)庫(kù)存,要么等用戶(hù)投訴吧。

?

解決這個(gè)問(wèn)題比較流行的思路:
1.用額外的單進(jìn)程處理一個(gè)隊(duì)列,下單請(qǐng)求放到隊(duì)列里,一個(gè)個(gè)處理,就不會(huì)有并發(fā)的問(wèn)題了,但是要額外的后臺(tái)進(jìn)程以及延遲問(wèn)題,不予考慮。


2.數(shù)據(jù)庫(kù)樂(lè)觀鎖,大致的意思是先查詢(xún)庫(kù)存,然后立馬將庫(kù)存+1,然后訂單生成后,在更新庫(kù)存前再查詢(xún)一次庫(kù)存,看看跟預(yù)期的庫(kù)存數(shù)量是否保持一致,不一致就回滾,提示用戶(hù)庫(kù)存不足。


3.根據(jù)update結(jié)果來(lái)判斷,我們可以在sql2的時(shí)候加一個(gè)判斷條件update ... where 庫(kù)存>0,如果返回false,則說(shuō)明庫(kù)存不足,并回滾事務(wù)。


4.借助文件排他鎖,在處理下單請(qǐng)求的時(shí)候,用flock鎖定一個(gè)文件,如果鎖定失敗說(shuō)明有其他訂單正在處理,此時(shí)要么等待要么直接提示用戶(hù)"服務(wù)器繁忙"

5.使用redis隊(duì)列來(lái),入列出來(lái)列

本文要說(shuō)的是第4種方案,大致代碼如下:
阻塞(等待)模式
<?php
$fp = fopen("lock.txt", "w+");
if(flock($fp,LOCK_EX)) ? //鎖定當(dāng)前指針,,,
{
? //..處理訂單
? flock($fp,LOCK_UN);
}
fclose($fp);
?>


非阻塞模式
<?php
$fp = fopen("lock.txt", "w+");
if(flock($fp,LOCK_EX | LOCK_NB))
{
? //..處理訂單
? flock($fp,LOCK_UN);
}
else
{
? echo "系統(tǒng)繁忙,請(qǐng)稍后再試";
}
fclose($fp);
?>

3.redis 高并發(fā)隊(duì)列秒殺

<?php $store=50; $redis=new Redis(); $result=$redis->connect('127.0.0.1',6379); $res=$redis->llen('pro38'); echo $res; $count=$store-$res; for($i=0;$i<$count;$i++){$redis->lpush('pro38',1); } echo $redis->llen('pro38'); ?>

上面是添加一個(gè)庫(kù)存為50的redis的list

下面貼上下單代碼

<?php include "MMysql.class.php"; $configArr=['host'=>'121.41.38.44','port'=>'3306','user'=>'yuancheng','passwd'=>'yuancheng','dbname'=>'laiyifendb', ]; $db = new MMysql($configArr); $redis=new Redis(); $result=$redis->connect('127.0.0.1',6379);$count=$redis->lpop('pro38'); if(!$count){echo "error:no store redis";return; } $sql="select * from sdb_b2c_products where product_id='38'"; $product=$db->doSql($sql); if(!$product){echo "error:not find product";return; } $product=$product[0]; if($product['store']-$product['freez']<1){echo "error:no store";return; } $sql="select * from sdb_b2c_member_addrs where member_id='256187'"; $addr=$db->doSql($sql); $addr=$addr[0]; $data=['order_id'=>date('ymdHis').rand(100,999),'total_amount'=>$product['price'],'final_amount'=>$product['price'],'pay_status'=>'0','createtime'=>time(),'shipping_id'=>'13','shipping'=>'韻達(dá)','member_id'=>'636389','ship_area'=>$addr['area'],'shipname'=>$addr['name'],'ship_addr'=>$addr['addr'], ]; $order=$db->insert('sdb_b2c_orders',$data); if($order){$sql="update sdb_b2c_products set freez=freez+1 where product_id='38'";$db->doSql($sql);echo "order create success";return; }else{echo "error:order create fail";return; }?>



經(jīng)過(guò)測(cè)試,此方法可以防止超賣(mài)的發(fā)生

轉(zhuǎn)載于:https://www.cnblogs.com/MyIsLu/p/6519007.html

新人創(chuàng)作打卡挑戰(zhàn)賽發(fā)博客就能抽獎(jiǎng)!定制產(chǎn)品紅包拿不停!

總結(jié)

以上是生活随笔為你收集整理的项目秒杀思路(转)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。