買いではプロジェクトは、株式の限られた数の問題で購入するときである、スパイク、懸賞やその他の活動に遭遇したが、同時に注文数が在庫数を超えた場合、商品が問題をオーバーブッキングにつながるようにします。以下のように、どのようにこの問題を解決するのです、私のアイデアがあります:
SQL1:商品在庫照会
(在庫数> 0)であれば
{
注文を生成する// ...
SQL2:在庫-1
}
何の並行処理が存在しない場合は、上記のプロセスはとても完璧と思われる、在庫にSQL1クエリで2件の受注、在庫のみの1、およびフェーズ2人が、>その後、最終的に実行さSQL2 0であることが想定されます最後に在庫が-1、オーバーブッキング、フィル在庫や顧客とのいずれかの苦情などになります。
この問題は、より多くの人気のアイデアを解決するには:
1.は、一つの処理によって追加の単一プロセス、キューに単一の要求、1でキューを処理し、問題があっ複雑になるが、追加のバックグラウンド・プロセスと遅延に、考慮されません。
2.データベース楽観的ロック、大体、その後、在庫+1を飛んで在庫を確認する意味、そして注文があればもう一度見るために、更新の株式インベントリー照会する前に、生成されたロールバックの一貫性の矛盾との株式数の期待値ユーザインベントリを要求するには不十分。
3.更新結果を判断して、我々はそれがfalseを返した場合の株式> 0は、それがバックトランザクションを在庫の不足、およびロールを示しSQL2時間...で条件の更新判定を追加することができます。
ロックが処理されている他の順序を示して失敗した場合に群れロックファイルとの排他的ロックファイル、単一の要求での処理時間、4.は、その後、いずれかの待機または直接「サーバービジー」にユーザーを促し
5. Redisのキュー、リストされた列
本明細書では第四の実施形態では、おおよそ次のコードを言うことです。
(待機)モードをブロック
<?phpの
$ FP =のfopen( "lock.txt"、 "W +");
(群れ($ fpは、LOCK_EX))//現在のポインタをロックした場合,,,
{
// ..プロセス指図
群れ($ fpは、LOCK_UN)。
}
fcloseを($ fpは);
?>
ノンブロッキングモード
<?phpの
$ FP =のfopen( "lock.txt"、 "W +");
もし(群れ($ fpは、LOCK_EX | LOCK_NB))
{
// ..プロセス指図
群れ($ fpは、LOCK_UN)。
}
そうしないと
{
「システムがビジー状態、後でもう一度試してください」エコー;
}
fcloseを($ fpは);
?>
高い同時キュースパイクを3.redis
<?phpの
= 50 $ストア;
$ Redisの=新しいRedisの();
$結果= $ redis->( '127.0.0.1'、6379)を接続します。
$ RES = $ redis-> LEN( 'pro38');
エコー解像度$;
$ = $ store- $ RESを数えます。
以下のために($ i = 0; $ iが<$カウント; $ I ++){
$ Redis-> lpush( 'pro38'、1);
}
エコー$ redis-> LEN( 'pro38');
?>
上記のRedisの50のリストに追加する株式であり、
次のコードは、上下単一に取り付けられています。
<?phpの
「MMysql.class.php」を含みます。
$ configArr = [
'ホスト' => '121.41.38.44'
'ポート' => '3306'
「ユーザー」=>「カゲン」
'passwdの' => 'カゲン'
'DBNAME' => 'laiyifendb'
];
$デシベル=新しいMMysql($ configArr)。
$ Redisの=新しいRedisの();
$結果= $ redis->( '127.0.0.1'、6379)を接続します。
$カウント= $ redis-> LPOP( 'pro38');
もし(!$回数){
エコー「エラー:なし店舗Redisの」;
リターン;
}
$ SQL = "sdb_b2c_productsから選択*どこのproduct_id = '38' "。
$製品= $ DB-> doSql($ SQL)。
もし(!$製品){
エコー「エラー:製品を見つけることができません」。
リターン;
}
$積= $製品[0]。
IF($積[ '店'] - $物[ 'FREEZ'] <1){
エコー「エラー:なしストア」。
リターン;
}
$ SQL = "MEMBER_ID = '256187' sdb_b2c_member_addrs SELECT * FROM";
$ ADDR = $ DB-> doSql($ SQL)。
$ ADDR = $ ADDR [0]。
$データ= [
'ORDER_ID' =>日付( 'ymdHis')。ランド(100999)
'TOTAL_AMOUNT' => $製品[ '価格']、
'final_amount' => $製品[ '価格']、
'pay_status' => '0'、
'CREATETIME' =>時間()
=> 'shipping_id' '13'、
'送料' => '韻'、
=> 'MEMBER_ID' '636389'、
'ship_area' => $ addrの[ '地域']、
'出荷先名' => $ addrの[ '名前']、
'ship_addr' => $ addrの[ 'ADDR']、
];
$順番= $ DB->挿入( 'sdb_b2c_orders'、$データ);
もし($順){
$ SQL = "更新sdb_b2c_productsセットFREEZ = FREEZ + 1ここでのproduct_id = '38' "。
$ DB-> doSql($ SQL)。
エコー「の成功を作成するために」。
リターン;
}そうしないと{
エコー「エラー:注文が作成できません」。
リターン;
}
?>