大家都知道在序列化隔離級別中引入了鍵範圍鎖定。鍵範圍鎖可防止其他事務插入其鍵值位於可序列化事務讀取的鍵值範圍內的新行,從而確保滿足此要求。但是對於鎖定的範圍真的清楚嗎?
前幾天看到有人對於鎖範圍的疑問,發現鎖定的資料比想象的要多。
下面我們看個例子:
---create tableand insert test data
create
table
test(c1
intprimary
key,
c2varchar(20
))insert
into
test
values(1
,'test'
),(2
,'test'
),(3
,'est')--
第乙個視窗查詢執行
settransaction
isolation
level
serializable
begin
tran
select
*from
test
where
c1 between
1 and3--
第二個視窗查詢執行
insert
into
test
values
(100
,'test'
)按照一般的理解,rang鎖應該會鎖定1-3的資料,不允許對其中的資料進行任何修改,所以插入100應該是可以正常執行的。 但是插入100的程序一直被block無法執行。
通過sys
.dm_tran_locks
的resource_description欄位我們可以看到「ffffffffffff」
,也就是說它的鍵範圍鎖是1,
2,3到無窮大,而並不少單純的1,
2,3。這個跟我們平常所理解的
rang範圍有衝突了。 檢視
msdn有乙個
注意:
包含的ranges-s鎖數量為n+1,此處n是滿足查詢條件的行數,
也就是說鍵範圍鎖的實際範圍為鍵範圍
+到下乙個
next
值之間的值(包含
next
值);
對比上面的例子,可以明白因為表中只有三條資料,相當於所有資料,
next
的值就是無窮大,所以
key-range
的範圍變成了無窮大。
如果我們現在插入記錄4再執行上面的語句可以看到執行成功(此時鎖定的記錄為
1-4,
100並不在這個範圍區間,所以可以成功插入)。
通過上面的例子可以看到
rang lock
的範圍比我們一般認識的要大,使用時要格外注意。
InnoDB實現序列化隔離級別的方法
序列化的實現 innodb對於序列化的實現方式,是通過兩種方式實現的。第一種,當select語句在乙個顯式的事務塊內,如執行表11 9中的編號為1的情況,將施加lock s鎖,根據表11 6 記錄鎖事務鎖相容表 可知,lock s鎖排斥寫鎖,所以序列化隔離級別下只允許併發地讀取操作,併發寫被禁止,因...
可序列化隔離級別裡的鎖公升級
在今天的文章裡我會討論下可序列化 serializable 隔離級別裡會有的鎖公升級 lock escalations 還有你如何避免。在上個月的7月14日,我已經介紹了sql server裡鎖公升級 lock escalations 的基本概念還有為什麼需要它們。因此請你回到這個文章來理解下這個非...
可序列化隔離級別裡的鎖公升級
可序列化 serializable 隔離級別用來阻止所謂的幻影記錄 phantom records 為了阻止它們,sql server使用鍵範圍鎖定 key range locking 技術。我們來看下面的select語句 1 select from person.address 2where st...