Im vorherigen Artikel „So verhindern Sie einen Überverkauf des Produktbestands bei hoher Parallelität“ haben wir über verwandte Probleme bei der Verhinderung eines Überverkaufs des Inventars bei hoher Parallelität gesprochen. Ich hoffe, es wird für alle hilfreich sein.
Dieser Artikel basiert auf dem Testfall „Wie man verhindert, dass Produktinventar bei hoher Parallelität in PHP überverkauft wird“. Empfohlenes Lernen: „PHP Learning Tutorial“
Während des gleichzeitigen Tests, Produkttabellen-ID = 1 Name = Daohuaxiang Rice Store = 15
请求总数30 每次10个并发 ab -n 30 -c 10 http://xxxxx.top/code/the_limit/add_order.php
Ergebnis:
Es gab 15 erfolgreiche Bestandsreduzierungen Der Lagerbestand hat 8 Mal eine negative Zahl von -7 und wird als unzureichender Lagerbestand beurteilt (negative Lagerbestände sind falsch und nicht zulässig). 15
请求总数30 每次10个并发 ab -n 30 -c 10 http://xxxxx.top/code/the_limit/unsigned.php
Der Lagerbestand zeigte 15 Mal einen negativen Wert von -6. Es wurde festgestellt, dass der Lagerbestand nicht ausreichte (negative Lagerbestandszahlen sind falsch und nicht zulässig). Nur das Hinzufügen zur Aktualisierung zur Abfrageanweisung hat kaum Auswirkungen auf das Sperren
3. MySQL-Transaktion, Sperroperationszeile
Anpassen zurück an Produkttabellen-ID =1 Name = Daohuaxiang Rice Store = 15
请求总数30 每次10个并发 ab -n 30 -c 10 http://xxxxx.top/code/the_limit/ACID.php
Es gab 15 erfolgreiche Lagerbestandsreduzierungen und der Lagerbestand erschien nicht negativ. 15 Es wird festgestellt, dass der Lagerbestand unzureichend ist (negative Lagerbestandszahlen sind falsch und nicht zulässig)Die Auswirkung des Hinzufügens von Transaktionen beträgt ab -n 3000 -c 1000 kann auch Parallelität standhalten
4. Nicht blockierende Datei-Exklusivsperre
Nicht blockierende Form
Der Effekt ist nicht negativ, aber in Bezug auf die Leistung: Transaktion > Blockierung > Nicht- Blockieren
Der Code wurde gegenüber der vorherigen optimistischen Sperrversion leicht angepasst
<?php $redis =new Redis(); $redis->connect("127.0.0.1", 6379); $redis->auth('PASSWORD'); $redis->watch('sales');//乐观锁 监视作用 set() 初始值0 $sales = $redis->get('sales'); //var_dump($sales); exit; db(); global $con; // 查询商品信息 //$product_id = 1; //$sql = "select * from products where id={$product_id}"; //$result = mysqli_query($con, $sql); //$row = mysqli_fetch_assoc($result); //$store = $row['store']; // 库存 $n = 15; if ($sales >= $n) { insertLog('库存为0 秒杀失败'); exit('秒杀结束'); } //redis开启事务 $redis->multi(); $redis->incr('sales'); //将 key 中储存的数字值增一 ,如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。 $res = $redis->exec(); //成功1 失败0 if ($res) { //秒杀成功 $con = new mysqli('localhost','root','PASSWORD','dev'); if (!$con) { echo "数据库连接失败"; } $product_id = 1;// 商品ID $buy_num = 1;// 购买数量 sleep(1); $sql = "update products set store=store-{$buy_num} where id={$product_id}"; if (mysqli_query($con, $sql)) { echo "秒杀完成"; insertLog('恭喜 秒杀成功'); } } else { insertLog('抱歉 秒杀失败'); exit('抢购失败'); } function db() { global $con; $con = new mysqli('localhost','root','WOrd1234.*','dev'); if (!$con) { echo "数据库连接失败"; } } /** * 记录日志 */ function insertLog($content) { global $con; $sql = "INSERT INTO `order_log` (content) values('$content')"; mysqli_query($con, $sql); }
ab -n 30 -c 10 http://xxxxxx.top/code/the_limit/optimistic\ _redis_lock.php
Empfohlenes Lernen: „
PHP-Video-Tutorial“
Das obige ist der detaillierte Inhalt vonPHP-Tests mit hoher Parallelität: Fallstudie zur Verhinderung überverkaufter Lagerbestände. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!