高併發和鎖

2021-09-20 04:01:41 字數 2746 閱讀 4112

面試被問到了這個問題,找了答案,記錄一下

假如有100w個使用者,搶一張票,除了負載均衡的辦法,怎麼支援高併發?

修改字段:將庫存欄位number欄位設為unsigned,當庫存為0時,因為字段不能為負數,將會返回false;

利用悲觀鎖(不適合高併發):悲觀鎖,也就是在修改資料的時候,採用鎖定狀態,排斥外部請求的修改。遇到加鎖的狀態,就必須等待;缺點:不適合高併發場景。每個請求都需要等待「鎖」,某些執行緒可能永遠都沒有機會搶到這個「鎖」,這種請求就會死在那裡。同時,這種請求會很多,瞬間增大系統的平均響應時間,結果是可用連線數被耗盡,系統陷入異常。

mysql事務:使用mysql的事務,鎖住操作的行;

//模擬下單操作

//庫存是否大於0

mysqli_query($conn,"begin"); //開始事務

$sql="select number from ih_store where goods_id='$goods_id' and sku_id='$sku_id' for update";//此時這條記錄被鎖住,其它事務必須等待此次事務提交後才能執行

$rs=mysqli_query($conn,$sql);

$row=$rs->fetch_assoc();

if($row['number']>0) where sku_id='$sku_id'";

$store_rs=mysqli_query($conn,$sql);

if($store_rs)else

}else

?>

fifo佇列(不適合高併發):直接將請求放入佇列中的,採用fifo(first input first output,先進先出),這樣的話,我們就不會導致某些請求永遠獲取不到鎖 ;缺點:不適合高併發。高併發的場景下,因為請求很多,很可能一瞬間將佇列記憶體「撐爆」,然後系統又陷入到了異常狀態。或者設計乙個極大的記憶體佇列,也是一種方案,但是,系統處理完乙個佇列內請求的速度根本無法和瘋狂湧入佇列中的數目相比。也就是說,佇列內的請求會越積累越多,最終web系統平均響應時候還是會大幅下降,系統還是陷入異常。

檔案鎖:對於日ip不高或者說併發數不是很大的應用,一般不用考慮這些!用一般的檔案操作方法完全沒有問題。但如果併發高,在我們對檔案進行讀寫操作時,很有可能多個程序對進一檔案進行操作,如果這時不對檔案的訪問進行相應的獨佔,就容易造成資料丟失

使用非阻塞的檔案排他鎖

<?php 

//優化方案4:使用非阻塞的檔案排他鎖

include ('./mysql.php');

//生成唯一訂單號

function build_order_no()

//記錄日誌

function insertlog($event,$type=0)

$fp = fopen("lock.txt", "w+");

if(!flock($fp,lock_ex | lock_nb))

//下單

$sql="select number from ih_store where goods_id='$goods_id' and sku_id='$sku_id'";

$rs = mysqli_query($conn,$sql);

$row = $rs->fetch_assoc();

if($row['number']>0) where sku_id='$sku_id'";

$store_rs = mysqli_query($conn,$sql);

if($store_rs)else

}else

fclose($fp);

?>

樂觀鎖(重要):樂觀鎖,是相對於「悲觀鎖」採用更為寬鬆的加鎖機制,大都是採用帶版本號(version)更新。實現就是,這個資料所有請求都有資格去修改,但會獲得乙個該資料的版本號,只有版本號符合的才能更新成功,其他的返回搶購失敗。這樣的話,我們就不需要考慮佇列的問題,不過,它會增大cpu的計算開銷。但是,綜合來說,這是乙個比較好的解決方案;如redis的watch

/* //插入搶購資料

if($mywatchkey>0)

else

}else*/

$rob_total = 100; //搶購數量

if($mywatchkey<=$rob_total)else

}?>

mysql悲觀鎖,高併發

1.高併發的時候有2種處理 1 後端進行執行緒安全處理,synchrnoized,還有其他不同粒度的鎖 2 在資料庫設定鎖,當你讀的時候,不允許其他人修改。可以用mysql的悲觀鎖 2.悲觀鎖 select from 表名 for update for update很重要,就是如果你查詢這個事務沒有...

java 高併發 之 鎖

synchronized 是屬於宣告式加鎖,可以修飾乙個 塊 乙個方法 乙個類,乙個靜態方法。修飾乙個 塊 public void test1 int j j,i 修飾乙個方法 public synchronized void test2 int j j,i 修飾乙個類 public static ...

高併發鎖的問題

場景分析,保護多個資源之間沒有業務關係 例如支付寶賬戶的針對餘額的操作,和針對賬戶密碼的修改操作。可以為賬戶資源,使用者資源分配不同的鎖來解決併發問題。public class alipayaccount 檢視賬戶中的餘額 public integer getbalance 修改賬戶的密碼 publ...