前幾天跟朋友聊天隧甚,聊起Mysql鎖的問題车荔。他突然問我為什么行鎖會(huì)變成表鎖。
由于解釋半天戚扳,他還沒搞明白忧便,因此用圖形化界面給他演示一下
首先準(zhǔn)備一張簡(jiǎn)單的測(cè)試表
準(zhǔn)備兩個(gè)窗體,且同時(shí)開啟事務(wù)
Session 1
begin;
select * from t1 where name = '張三' for update;
ROLLBACK
COMMIT
/****************************************************************************/
Session 2
begin;
select * from t1 where id = 3 for update;
ROLLBACK
COMMIT
session2 因?yàn)樾墟i升級(jí)為表鎖一直在等待
InnoDB 行級(jí)鎖是通過給索引上的索引項(xiàng)加鎖來實(shí)現(xiàn)的帽借,InnoDB行級(jí)鎖只有通過索引條件檢索數(shù)據(jù)茬腿,才使用行級(jí)鎖;否則,InnoDB使用表鎖 在不通過索引(主 鍵)條件查詢的時(shí)候宜雀,InnoDB是表鎖而不是行鎖。
總結(jié):就是在沒有使用索引的情況下InnoDB就會(huì)使用表級(jí)鎖(共享鎖不會(huì)有這個(gè)情況)
最后給出事務(wù)使用的幾點(diǎn)建議
- 控制事務(wù)大小握础,減少鎖定的資源量和鎖定時(shí)間長(zhǎng)度辐董。
- 所有的數(shù)據(jù)檢索都通過索引來完成,從而避免因?yàn)闊o法通過索引加鎖而升級(jí)為表鎖禀综。
- 減少基于范圍的數(shù)據(jù)檢索過濾條件简烘,避免因?yàn)殚g隙鎖帶來的負(fù)面影響而鎖定了不該鎖定的數(shù)據(jù)。
- 在業(yè)務(wù)條件允許下定枷,盡量使用較低隔離級(jí)別的事務(wù)隔離孤澎。減少隔離級(jí)別帶來的附加成本。
- 合理使用索引欠窒,讓innodb在索引上面加鎖的時(shí)候更加準(zhǔn)確覆旭。
- 在應(yīng)用中盡可能做到訪問的順序執(zhí)行。
- 如果容易死鎖,就可以考慮使用表鎖來減少死鎖的概率