键范围锁定(Key-Rang Lock)是不是只在序列化级别中出现

简介:

以前一直认为键范围锁定只是在序列化隔离级别中才会出现,但是从论坛的一篇帖子中看到Read-Committed隔离级别中竟然也出现了:

59:50. spid24s process id=process6463b88 taskpriority=0 logused=480 waitresource=KEY: 6:72057594065715200 (8500ea663c04) waittime=516 

ownerId=773364767 transactionname=test lasttranstarted=2013-06-04T08:59:49.450 
XDES=0x80092570 lockMode=RangeS-U schedulerid=22 kpid=2872 status=suspended 

spid=57 sbid=0 ecid=0 priority=0 trancount=3 

lastbatchstarted=2013-06-04T08:59:49.453 lastbatchcompleted=2013-06-04T08:59:49.450 
isolationlevel=read committed (2) xactid=773364767 currentdb=6 lockTimeout=4294967295 
clientoption1=671088672 clientoption2=128056

之后查到两片文章提到SQL Server在一定的条件下会隐式的提升隔离级别到序列化。

微软用级联删除的例子做了说明:

createtableFoo(FooIdintnotnullprimarykey)

createtableBar(FooIdintnotnull,BarIdintnotnull)

altertableBaraddconstraintPK_Barprimarykey (FooId,BarId)

altertableBaraddconstraintFK_Bar_Fooforeignkey (FooId)referencesFoo(FooId)ondeletecascade

insertintoFoovalues (1)insertintoBarvalues (1, 1)

settransactionisolationlevelreadcommitted

begintran

deletefromFoowhereFooId= 1 

committran

删除的操作需要保持:

1.删除Foo 表的数据其实也要删除Bar表中相关联的数据

2.在语句结束的时候,外键约束还是有效的。

所以在read-committed隔离级别下,X locks一直持续到交易结束,但是不能避免在删除的同时其他人插入数据。所以需要SERIALIAZABLE隔离级别。

所以,对于类似的操作,不需要用户显示的使用serialization 隔离级别,SQL Server会自动将隔离级别升级从而阻塞其他操作插入数据从而影响外键约束。在这种情况下,SQL Server会使用键范围锁定.这种方法可以避免数据损坏。

SERIALIZABLE级别的锁会一直保持到交易结束,如果一个批次中有多条语句,可能需要一段时间释放这些锁。因为SQL Server知道使用了什么锁,并且什么时候释放才是安全的。

 

另外索引视图维护也是相同的情况。

更多资料可以参考:Read Committed isolation level, indexed views and locking behavior

Conor vs. Isolation Level Upgrade on UPDATE/DELETE Cascading RI

 

本文转自 lzf328 51CTO博客,原文链接:

http://blog.51cto.com/lzf328/1217126
相关文章
|
7月前
【报错】win键被锁怎么解锁
【报错】win键被锁怎么解锁
136 0
解决线程安全问题的方式三:Lock锁 ---JDK5.0新增
解决线程安全问题的方式三:Lock锁 ---JDK5.0新增
32 0
|
存储 设计模式 缓存
C# 实现 key-value 结构自定义缓存 CustomCache
C# 实现 key-value 结构自定义缓存 CustomCache
188 1
C# 实现 key-value 结构自定义缓存 CustomCache
|
SQL 关系型数据库 MySQL
当并发insert on duplicate key update遇见死锁:更新丢失
数据库死锁问题,是一个老生常谈且很常见的问题,网上也有非常多对于各类死锁场景的解析和复现,但凡和死锁有关,无外乎不涉及数据库隔离等级、索引、以及innodb锁等相关原因。但是我这个案例我搜遍了全网也没能找到比较相似情况。于是我想尽可能的复现出这种情况,找出死锁的原因,找出可能出现的隐患。问题的背景:我们的数据库中的发生死锁的表是具有”多列组合构建的唯一索引“(不包含
19529 4
|
SQL C# 数据库
C#编程学习16:清除access中某个数据表的所有数据并重置ID从1自增
C#编程学习16:清除access中某个数据表的所有数据并重置ID从1自增
C#编程学习16:清除access中某个数据表的所有数据并重置ID从1自增
|
Oracle 关系型数据库
ORA-01779: 无法修改与非键值保存表对应的列
ORA-01779: 无法修改与非键值保存表对应的列
ORA-01779: 无法修改与非键值保存表对应的列
CString的GetBuffer()主要作用是将字符串的缓冲区长度锁定,releaseBuffer则是解除锁定
CString的GetBuffer()主要作用是将字符串的缓冲区长度锁定,releaseBuffer则是解除锁定
225 0
|
缓存 NoSQL Java
缓存系列文章--8.热点key问题(mutex key)
   转载请注明出处哈:http://carlosfu.iteye.com/blog/2269678  一、引出热点key问题          我们通常使用 缓存 + 过期时间的策略来帮助我们加速接口的访问速度,减少了后端负载,同时保证功能的更新,一般情况下这种模式已经基本满足要求了。
1274 0