並發 php 抽獎
我的做法是比如:一等獎:1個,二等獎:2個,三等級:3個,這樣有獎項為6,假如100人同時參與抽獎,那麼空獎項為100-6=94項。
首先從資料庫mysql查詢出有獎項6個的唯一編號作為兌獎號:
sql1:
$sql="select 唯一編號 from table where status=0";
得到數組$real=array('001','002','003','004','005','006',);其中001,002就是唯一編號
然後產生94個空獎
$empty=array('','',...,'',);
最後把數組合并,得到一個全新的數組。
$arr = array_merge($real, $empty);
使用者隨機在數組中抽取一項
$rand= mt_rand(0, count($arr)-1);
比如$rand抽到了001
if(''!=$rand){
//表示抽中,修改資料狀態,這裡需要操作資料庫
sql2:
$sql="update table set status=1 where 唯一編號=001";
操作完成
}else{
//表示沒有抽中,不做操作。
}
現在的問題是當100人同時進入抽獎,在紅色部分sql2,還沒有來的急修改狀態的情況下,sql1繼續會把001作為沒有抽中的獎項,來讓其他使用者繼續抽,這樣有可能001再次被抽到。
想請大家協助php高並發下抽獎程式,如何避免重複中獎及多人抽中同一個獎?
或者從別的思路出發考慮抽獎程式。
回複討論(解決方案)
很難想象你是設計怎麼會是一邊參加一邊抽獎……
參加抽獎不設截止時間的嗎?如果有那就是兩個過程,問題不存在了
很難想象你是設計怎麼會是一邊參加一邊抽獎……
參加抽獎不設截止時間的嗎?如果有那就是兩個過程,問題不存在了
截止時間是有的啊 比如抽獎時間為今天2013-09-15截止2013-10-15號
你能詳細介紹一下你的方案嗎?
既然有截止時間,那跟高並發有啥關係?
讀出合資格的到一個數組,抽一次就把抽出來的從數組去掉,依次抽獎就是了
既然有截止時間,那跟高並發有啥關係?
讀出合資格的到一個數組,抽一次就把抽出來的從數組去掉,依次抽獎就是了
sql1 未中獎的編號有001 002 003 004 005 006
sql2 中使用者1中了001,正常情況下未中獎的編號剩002 003 004 005 006
特殊情況下當sql2還未來的急修改001中獎狀態為已中獎的情況下,使用者2查詢sql1得到的未中獎編號還會是001 002 003 004 005 006這樣使用者2也有可能再次中001
你這個是線上遊戲?需要用戶端參與?
1、生產成獎池 $arr = array_merge($real, $empty);
2、儲存於檔案或獨立表中
3、抽獎時以獨佔方式開啟檔案或表(後續的抽獎這隻能排隊來等待資源的釋放)
4、修改獎池並釋放資源
無論是即開即兌還是到期一次性對付的都可以如法炮製
抽獎並發,讓每個使用者實現隊列抽獎。
1、生產成獎池 $arr = array_merge($real, $empty);
2、儲存於檔案或獨立表中
3、抽獎時以獨佔方式開啟檔案或表(後續的抽獎這隻能排隊來等待資源的釋放)
4、修改獎池並釋放資源
無論是即開即兌還是到期一次性對付的都可以如法炮製
應該就是隊列吧。
直接存memcache是不是更好呢?
這是PHP的一個特點(或缺點),因為它是多進程獨立的,本身無法解決並發同步的問題,可以藉助其它程式來實現,比如利用Memcached單線程的特性。