因爲InnoDB預設是Row-Level Lock,因此只有「明確」的指定主鍵,MySQL纔會執行Row lock (只鎖住被選取的資料例) ,不然MySQL將會執行Table Lock (將整個資料表單給鎖住)。測試
舉個例子: 假設有個表單products ,裏面有id跟name二個欄位,id是主鍵。spa
例1: (明確指定主鍵,而且有此筆資料,row lock)
orm
複製代碼代碼以下:索引
SELECT * FROM products WHERE id='3' FOR UPDATE;
SELECT * FROM products WHERE id='3' and type=1 FOR UPDATE;it
例2: (明確指定主鍵,若查無此筆資料,無lock)
io
複製代碼代碼以下:table
SELECT * FROM products WHERE id='-1' FOR UPDATE;表單
例3: (無主鍵,table lock)
date
複製代碼代碼以下:float
SELECT * FROM products WHERE name='Mouse' FOR UPDATE;
例4: (主鍵不明確,table lock)
複製代碼代碼以下:
SELECT * FROM products WHERE id<>'3' FOR UPDATE;
例5: (主鍵不明確,table lock)
複製代碼代碼以下:
SELECT * FROM products WHERE id LIKE '3' FOR UPDATE;
注1: FOR UPDATE僅適用於InnoDB,且必須在交易區塊(BEGIN/COMMIT)中才能生效。
注2: 要測試鎖定的情況,能夠利用MySQL的Command Mode ,開二個視窗來作測試。
-----------------------------------------第二次編輯分割線--------------------------------------
假設kid 是表table 的 一個索引字段 且值不惟一
1.若是kid 有多個值爲12的記錄那麼:
update table set name=’feie’ where kid=12;會鎖表
2.若是kid有惟一的值爲1的記錄那麼:
update table set name=’feie’ where kid=1;不會鎖
總結:用索引字段作爲條件進行修改時, 是否表鎖的取決於這個索引字段可否肯定記錄惟一,當索引值對應記錄不惟一,會進行鎖表,相反則行鎖。