說在前面:基於innodb討論
1.insert時全表鎖,update是行級鎖(非絕對-成功使用索引時鎖行,否則鎖表)
2.是否使用行鎖分析
3.行表鎖總結:
1)表級鎖 開銷小,吞吐量會減小
2)行級鎖 消耗大,吞吐量也大
3)MyISAM只支持表級鎖;InnoDB支持行級鎖(分為共享鎖與排它鎖),可以使用表鎖;
當前讀(除顯式in share外,包括update都是拍他鎖)
4)innodb一般情況下走索引或者主鍵更新都是鎖行,其余都是鎖表,在並發的時候可以加select for update手工鎖
4. InnoDB表,主要有以下幾點
(1)InnoDB的行銷是基於索引實現的,如果不通過索引訪問數據,InnoDB會使用表鎖。
(2)InnoDB間隙鎖機制,以及InnoDB使用間隙鎖的原因。
(3)在不同的隔離級別下,InnoDB的鎖機制和一致性讀策略不同。
(4)MySQL的恢復和復制對InnoDB鎖機制和一致性讀策略也有較大影響。
(5)鎖沖突甚至死鎖很難完全避免。
在了解InnoDB的鎖特性后,用戶可以通過設計和SQL調整等措施減少鎖沖突和死鎖,包括:
- 盡量使用較低的隔離級別
- 精心設計索引,並盡量使用索引訪問數據,使加鎖更精確,從而減少鎖沖突的機會。細粒度
- 選擇合理的事務大小,小事務發生鎖沖突的幾率也更小。
- 給記錄集顯示加鎖時,最好一次性請求足夠級別的鎖。比如要修改數據的話,最好直接申請排他鎖,而不是先申請共享鎖,修改時再請求排他鎖,這樣容易產生死鎖。
- 不同的程序訪問一組表時,應盡量約定以相同的順序訪問各表,對一個表而言,盡可能以固定的順序存取表中的行。這樣可以大減少死鎖的機會。
- 盡量用相等條件訪問數據,這樣可以避免間隙鎖對並發插入的影響。
- 不要申請超過實際需要的鎖級別;除非必須,查詢時不要顯示加鎖。
- 對於一些特定的事務,可以使用表鎖來提高處理速度或減少死鎖的可能。
5.要修改數據,首先要找到數據,而如果沒有索引,就會直接鎖住表的數據,就會鎖住其他的會話。
6.InnoDB行鎖是通過給索引上的索引項加鎖來實現的
附:
共享鎖與排他鎖
1.首先說明:數據庫的增刪改操作默認都會加排他鎖,而查詢不會加任何鎖。
|--共享鎖:對某一資源加共享鎖,自身可以讀該資源,其他人也可以讀該資源(也可以再繼續加共享鎖,即 共享鎖可多個共存),但無法修改。要想修改就必須等所有共享鎖都釋放完之后。語法為:
select * from table lock in share mode
|--排他鎖:對某一資源加排他鎖,自身可以進行增刪改查,其他人無法進行任何操作。語法為:
select * from table for update