一條select語句后面跟了for update,一時間就來了興趣。
幾番搜索之后,明白這是一個上鎖用的。
上的是一個排它鎖,也就是說,其他的事務是可以讀取的。但是不能寫入或者更新。
我們舉一個項目中常見的應用場景吧。
比如有一張表 他有三個字段。id代表商品id ,name代表商品名字,count代表該商品數量。
我們為了顯示搶購的時候顯示該商品還剩余多少件。我們會手動的上鎖。鎖住id為1的商品。比如id為1的商品名字是某型號的mac pro。count代表了該商品還剩余多少件。當並發量很大的情況下,商品數量自減的值可能是不准確的。
所以當我們在一個事務中對count字段進行修改的時候,其他的事務應該是只能讀取指定id的count值。而不能寫入或者update。這個時候for update的作用就是在此刻體現的。
比如說sql是這樣的。
start transaction ; select * from table_name where id =1 for update ; update table_name set count = count - 1 where id= 1;
此時如果另一個事務也想執行類似的操作。
start transaction ; select * from table_name where id =1 for update ; //下面的這行sql會等待,直到上面的事務回滾或者commit才得到執行。 update table_name set count = count - 1 where id= 1;
順帶一提的是,當選中某一個行的時候,如果是通過主鍵id選中的。那么這個時候是行級鎖。
其他的行還是可以直接insert 或者update的。如果是通過其他的方式選中行,或者選中的條件不明確包含主鍵。這個時候會鎖表。其他的事務對該表的任意一行記錄都無法進行插入或者更新操作。只能讀取。
for update 必須在事務中執行
(避免高並發時庫存為負數)
where條件有主鍵是行鎖 否則是表鎖
