<?php /** * 超卖实验(使用文件保存库存,也可以使用数据库保存库存) */ $stockFile = __DIR__ . '/stock.txt'; $stockTotal = 10; // 总库存 /** * 获得微秒时间戳(16位数字串) * * @return int 微秒时间戳(16位数字串) */ function us_time() { list($usec, $sec) = explode(' ', microtime()); return $sec . substr(strval($usec), 2, 6); } /** * 重置测试环境 * * @return void */ function reset_env() { global $stockFile; global $stockTotal; file_put_contents($stockFile, $stockTotal); exit('reset'); } // reset_env(); // 每次进行实验前记得先重置测试环境 session_start(); $sessionId = session_id(); $ustime = us_time(); $stock = intval(file_get_contents($stockFile)); // 获取库存数 if ($stock >= 1) { $stock--; // 库存减1 file_put_contents($stockFile, $stock); $index = $stockTotal - $stock; $file = __DIR__ . "/{$ustime}.抢到了(第{$index}个).{$sessionId}.txt"; } else { $file = __DIR__ . "/{$ustime}.没抢到.{$sessionId}.txt"; } file_put_contents($file, ''); /** * 实验结果: * 出现了超卖现象,且从时间线上看并不是还有库存前面的人就一定会抢到,即可 * 能出现第1、2、3人抢到,但第4、5人又没抢到的情况。 */
<?php /** * 超卖实验(使用Redis保存库存) */ $redis = new Redis(); $redis->connect('localhost', 6379); $redis->auth('密码'); $stockTotal = 10; // 总库存 $redis->setnx('stock', $stockTotal); // 把总库存放入Redis /** * 获得微秒时间戳(16位数字串) * * @return int 微秒时间戳(16位数字串) */ function us_time() { list($usec, $sec) = explode(' ', microtime()); return $sec . substr(strval($usec), 2, 6); } /** * 重置测试环境 * * @return void */ function reset_env() { global $redis; $redis->flushAll(); exit('reset'); } // reset_env(); // 每次进行实验前记得先重置测试环境 session_start(); $sessionId = session_id(); $ustime = us_time(); $stock = $redis->decr('stock'); // 库存减1(返回值为自减后的值,提示:最后一个被抢到时返回值为0) if ($stock >= 0) { $index = $stockTotal - $stock; $file = __DIR__ . "/{$ustime}.抢到了(第{$index}个).{$sessionId}.txt"; } else { $file = __DIR__ . "/{$ustime}.没抢到.{$sessionId}.txt"; } file_put_contents($file, ''); /** * 实验结果: * 没有出现超卖现象,且从时间线上看就是前10个用户抢光了10个库存,完美解决了超卖问题。 */
Copyright © 2024 码农人生. All Rights Reserved