在電子商務裡,經常會出現庫存數量少,購買的人又特別多,大併發情況下如何確保商品數量不會被多次購買.
其實很簡單,利用事務+for update就可以解決.
我們都知道for update實際上是共享鎖,是可以被讀取的.但是如何在執行時,不被讀取呢.
簡單來說:假設現在庫存為1,現在有a和b同時購買
先開啟乙個事務
begin;
select stock from good where id=1 for update;//查詢good表某個商品中stock的數量
查出來後,在程式裡在判斷這個stock是否為0(你用什麼語言,不關我事)
最後在執行
update good set stock=stock-1 where id=1
最後在commit
但是這個時候b也是select stock from good where id=1 for update;注意:for update不能省略..這個時候會出現被鎖住,無法被讀取.
所以這就能夠保證了商品剩餘數量為1的一致性.
mysql中使用select for update的必須針對innodb,並且是在乙個事務中,才能起作用。
select的條件不一樣,採用的是行級鎖還是表級鎖也不一樣。
轉的說明
由於 innodb 預設是 row-level lock,所以只有「明確」的指定主鍵,mysql 才會執行 row lock (只鎖住被選取的資料例) ,否則 mysql 將會執行 table lock (將整個資料表單給鎖住)。
舉個例子:
假設有個表單 products ,裡面有 id 跟 name 二個字段,id 是主鍵。
例1: (明確指定主鍵,並且有此筆資料,row lock)
select * from products where id='3' for update;
例2: (明確指定主鍵,若查無此筆資料,無 lock)
select * from products where id='-1' for update;
例2: (無主鍵,table lock)
select * from products where name='mouse' for update;
例3: (主鍵不明確,table lock)
select * from products where id<>'3' for update;
例4: (主鍵不明確,table lock)
select * from products where id like '3' for update;
注1:for update 僅適用於 innodb,且必須在交易區塊(begin/commit)中才能生效。
注2:要測試鎖定的狀況,可以利用 mysql 的 command mode ,開二個視窗來做測試。
mysql行鎖詳解 詳解MySQL行鎖
鎖是計算機協調多個程序或執行緒併發訪問某一資源的機制。鎖保證資料併發訪問的一致性 有效性 鎖衝突也是影響資料庫併發訪問效能的乙個重要因素。鎖是mysql在伺服器層和儲存引擎層的的併發控制。mysql中從對資料操作的粒度分為表鎖和行鎖。表鎖是指對一整張表加鎖,一般是 ddl 處理時使用 而行鎖則是鎖定...
mysql行鎖的特性 MySql的表鎖行鎖及間隙鎖
常用命令 手動新增表鎖 lock table 表名稱 read write 表名稱2 read write 檢視表上加過的鎖 show open tables 刪除表鎖 unlock tables 1.表鎖 特點 1.每次操作鎖住整張表,開銷小,加鎖快 2.不會出現死鎖 3.鎖定粒度大,發生鎖衝突的...
mysql行鎖表鎖區別 mysql表鎖和行鎖區別
一 表鎖 特點 偏向myisam儲存引擎,開銷小,加鎖快 無死鎖 鎖定粒度大,發生鎖衝突的概率最高,併發度最低。我們在編輯表,或者執行修改表的事情了語句的時候,一般都會給表加上表鎖,可以避免一些不同步的事情出現,表鎖分為兩種,一種是讀鎖,一種是寫鎖。我們可以手動給表加上這兩種鎖,語句是 lock t...