一.概述 Innodb 行鎖是通過給索引上的索引項加鎖來實現的。這一點與(oracle,sql server)不同後者是通過在數據塊中對相應的數據行加鎖。這意味著只有通過索引條件檢索數據,innodb才使用行級鎖,否則 innodb將使用表鎖。 在實際應用中,特別要註意innodb行鎖的這一特性,不 ...
一.概述
Innodb 行鎖是通過給索引上的索引項加鎖來實現的。這一點與(oracle,sql server)不同後者是通過在數據塊中對相應的數據行加鎖。這意味著只有通過索引條件檢索數據,innodb才使用行級鎖,否則 innodb將使用表鎖。
在實際應用中,特別要註意innodb行鎖的這一特性,不然的話,可能導致大量的鎖衝突,從而影響併發性能。下麵來實際演示說明:
1. innodb 的表條件CityCode不使用索引時,使用的是表鎖例子
-- 查詢表中數據共二條 SELECT * FROM city;
-- 條件欄位CityCode不走索引 EXPLAIN SELECT * FROM city WHERE CityCode='001'
會話1 |
會話2 |
SET autocommit=0; SELECT * FROM city WHERE CityCode='001'; city_id country_id cityname CityCode 14 2 深圳 001 |
SET autocommit=0; SELECT * FROM city WHERE CityCode='002'; city_id country_id cityname CityCode 15 2 長沙 002 |
-- 加鎖 SELECT cityname FROM city WHERE CityCode='001' FOR UPDATE ; cityname 深圳 |
|
|
-- 加鎖 SELECT cityname FROM city WHERE CityCode='002' FOR UPDATE ; 等待... 錯誤代碼: 1205 Lock wait timeout exceeded; try restarting transaction |
通過上面的案例 會話1只給一行加了排它鎖, 但會話2在請求其它行的排他鎖時,卻出現了鎖等待。原因就是在沒有索引的情況下,innodb只能使用表鎖。
2. innodb 的表條件CityCode使用索引時,使用的是行鎖例子
-- 添加索引 ALTER TABLE city ADD INDEX ix_citycode(CityCode) -- CityCode走索引 EXPLAIN SELECT * FROM city WHERE CityCode='001'
會話1 |
會話2 |
SET autocommit=0; SELECT * FROM city WHERE CityCode='001'; city_id country_id cityname CityCode 14 2 深圳 001 |
SET autocommit=0; SELECT * FROM city WHERE CityCode='002'; city_id country_id cityname CityCode 15 2 長沙 002 |
-- 加鎖 SELECT cityname FROM city WHERE CityCode='001' FOR UPDATE ; cityname 深圳 |
|
|
-- 加鎖 SELECT cityname FROM city WHERE CityCode='002' FOR UPDATE ; cityname 長沙 |