一 、基本概念
innodb支援幾種不同的行級鎖,myisam只支援表級鎖
行鎖(record lock):對索引記錄加鎖。
間隙鎖(gap lock):鎖住整個區間,包括:區間裡具體的索引記錄,不存在的空閒空間(可以是兩個索引記錄之間,也可能是第乙個索引記錄之前或最後乙個索引記錄之後的空間)。
next-key鎖:行鎖和間隙鎖組合起來。
注意:如果檢索條件不是索引的話會全表掃瞄,則是表級鎖,不是行級鎖
二、行鎖(record lock)
對主鍵或者唯一索引進行增刪改或顯示的加鎖,innodb會加行鎖,如:
-- 顯示的加鎖
select * from people where id =
3for update;
update people set name=
'james' where id=
3
注意:
正常的查詢語句使用的是共享鎖。
對於顯示的加鎖或增刪改操作,條件判斷必須是精確匹配(也就是=) ,不能用》,<,between或like等範圍查詢方式,因為這樣會使行鎖變成next-key lock。
三、間隙鎖(gap lock)
官方文件描述:gap lock的唯一目的就是阻止其他事務插入到間隙中。gap lock可以同時存在,不同的事務可以同時獲取相同的gap lock,並不會互相衝突。gap lock也是可以顯示的被禁止的,只要將事務的隔離級別降低到 read committed。對於間隙鎖,什麼叫鎖住不存在的空閒空間,舉個例子:
乙個表有id為1,2,3,5,6,9行資料,執行如下sql語句
select * from people where id >
3 and id <
7for update;
這是乙個範圍檢索,innodb不僅會鎖住id為5和6兩行的資料,也會鎖住id為4(雖然該行並不存在)的紀錄。
四、next-key lock
官方文件描述:record lock+gap lock,如果乙個事務在記錄r上的某個索引有共享/互斥鎖,也會對其前面乙個範圍加鎖鎖定的區域
根據索引會形成乙個個左開右閉的乙個區間,根據查詢的條件其所在的區間,並且包括其後的區間。
這裡給出乙個people表
idname
age1
james372
oven283
love
34如果age是索引的話,相關的區域有
(-無窮,28]
(28,34]
(34,37]
(37,+無窮)
如果執行如下語句:
select * from people where age =
34for update;
那麼會鎖住(28,37]這麼範圍
如果執行如下語句:
select * from people where age =
33for update;
那麼會鎖住(28,34)這麼範圍
間隙鎖的目的是為了防止幻讀,其主要通過兩個方面實現這個目的:
(1)防止間隙內有新資料被插入
(2)防止已存在的資料,更新成間隙內的資料
innodb自動使用間隙鎖的條件:
(1)必須在repeatable read級別下
(2)檢索條件必須有普通索引(沒有索引的話,mysql會全表掃瞄,那樣會鎖定整張表所有的記錄,包括不存在的記錄,此時其他事務不能修改不能刪除不能新增)
注意:這裡的普通索引不包括主鍵索引和唯一索引,如果在這兩個索引下因為能精確檢索出結果,所以會使用record lock直接鎖定具體的行(範圍查詢除外)。
舉例: 對於表people
mysql> select * from people ;+--
--+-------
+| id | name |+--
--+-------
+|1| james ||2
| oven ||3
| love |+--
--+-------
+
時間順序
session a
session b
1begin;
2begin;
3select * from people where name=「oven」 for update ;(查詢到「oven」)
4update people set name=「zph」 where id=1; (此操作會被鎖住)
因為通過name索引執行select …for update會將(1,「james」)到(3,「love」)之間的資料都鎖住,所以第4步會被鎖住。
但是如果通過id主鍵索引來檢索
時間順序
session a
session b
1begin;
2begin;
3select * from people where id=2 for update ;(查詢到「oven」)
4update people set name=「zph」 where id=1; (此操作會被執行)
對於間隙鎖的許多例子可以看mysql中的幾種行鎖(間隙鎖、next-key鎖)
這個部落格中的顯示不了,可以通過下面的url訪問五 、快照讀和當前讀
快照讀:通過mvcc實現,該技術不僅可以保證innodb的可重複讀,而且可以防止幻讀。但是他讀取的資料雖然是一致的,但是資料是歷史資料。
簡單的select操作(不包括 select … lock in share mode, select … for update)
當前讀:要做到保證資料是一致的,同時讀取的資料是最新的資料。innodb提供了next-key lock,即gap鎖與行鎖結合來實現。
select … lock in share mode
select … for update
insert
update
delete
總結在可重複讀隔離級別下並不能避免幻讀,如果要避免的話需要使用next-key lock。但是有了next-key lock以後,會導致併發插入的時候產生等待,所以這時候需要進行相關的優化。
參考mysql的鎖機制
mysql中的幾種行鎖(間隙鎖、next-key鎖)
mysql資料庫間隙鎖(mysql是如何解決幻讀的)
MySQL 表鎖 行鎖 間隙鎖
表鎖 表鎖有兩種模式 表共享讀鎖 表獨佔寫鎖 表共享讀鎖 讀鎖不會阻塞其他程序對同一表的讀操作,但阻塞寫操作,只有釋放鎖後其他程序才可以寫 表獨佔寫鎖 寫鎖會阻塞其他程序對同一表的讀和寫,只有寫鎖釋放後,其他程序才可以讀寫 簡而言之 讀鎖會阻塞寫,不阻塞讀 寫鎖阻塞讀和寫。行鎖 只鎖住某一行或多行的...
mysql間隙鎖 mysql間隙鎖
前面一文 mysql鎖 介紹了mysql innodb儲存引擎的各種鎖,本文介紹一下innodb儲存引擎的間隙鎖,就以下問題展開討論 1.什麼是間隙鎖?間隙鎖是怎樣產生的?2.間隙鎖有什麼作用?3.使用間隙鎖有什麼隱患?一 間隙鎖的基本概念 1.什麼叫間隙鎖 當我們用範圍條件而不是相等條件檢索資料,...
mysql 間隙鎖 mysql間隙鎖 轉
前面一文 mysql鎖 介紹了mysql innodb儲存引擎的各種鎖,本文介紹一下innodb儲存引擎的間隙鎖,就以下問題展開討論 1.什麼是間隙鎖?間隙鎖是怎樣產生的?2.間隙鎖有什麼作用?3.使用間隙鎖有什麼隱患?一 間隙鎖的基本概念 1.什麼叫間隙鎖 當我們用範圍條件而不是相等條件檢索資料,...