標籤:ble record charset err while mys 時間 開始時間 div
搶購情境中,要保證兩點:
1.庫存不會超減/少賣
2.在1基礎上的執行速度
我測試了兩種方案,
方案一.Mysql開啟事務
我把庫存表簡單設計如下
CREATE TABLE `la_store` ( `id` int(11) NOT NULL, `val` int(255) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
假設庫存有100000件(val=100000)
php邏輯代碼
<?php$stime=microtime(true);$count=100000;//測試次數while($count>0){$count-=1;$con = mysql_connect("localhost","user","pwd");if (!$con) { die(‘Could not connect: ‘ . mysql_error()); }mysql_select_db("database_name", $con);mysql_query(‘begin‘);$record=mysql_query("select * from la_store where id = 1 for update");//擷取獨佔鎖$record=mysql_fetch_array($record);if($record[‘val‘]>0){//判斷是否還有庫存//有庫存的邏輯$res=mysql_query("UPDATE la_test SET val = val-1 WHERE id=1 ");//更新庫存}else{
//沒庫存的邏輯
}mysql_query("commit");mysql_close($con);}$etime=microtime(true);//擷取程式執行結束的時間$total=$etime-$stime;echo $total;
方案二.使用Redis開啟事務
假設庫存有100000件(set store 100000)
<?php$stime=microtime(true);//開始時間$count=100000;//測試次數while($count>0){$count-=1;$redis = new Redis(); $redis->connect(‘127.0.0.1‘, 6379);$res=$redis->multi()->decr(‘store‘)->get(‘store‘)->exec();if($res[1]>0){ //有庫存邏輯}else{ //沒有庫存邏輯}}$etime=microtime(true);//擷取程式執行結束的時間print_r($res);$total=$etime-$stime;echo $total;
測試結果:
分別執行,經過100000次迴圈後,Redis用時22秒,Mysql用時50秒;
使用Redis更快,但Redis的事務不能復原,如果商務邏輯出錯時允許不復原,並且復原的機率很小,建議使用Redis.如果邏輯出錯時必須復原,還是用Mysql更穩妥.
使用Mysql和Redis設計搶購邏輯