场景:
嵌入在包装器 TransactionScope(TransactionScopeOption.Required) 中的 TransactionScope(TransactionScopeOption.Suppress) 查询。在“抑制”查询之前,还有另一个与包装“必需”TransactionScope 关联的查询。
这两个查询只在一张表上重叠。前面的“必需”查询插入到表中,后面的“抑制”查询从表中选择。忽略这是多么愚蠢,“抑制”查询只会读取未锁定的行,因此不会包括新插入的结果。
行为:
我看到的行为是,如果表中有行,则插入将成功,然后选择将读取未锁定的行,然后继续。但是,如果表为空,则 Insert 会成功,但 Select 会因为被 Insert 阻塞而卡住。
问题:
我想要获得的是对在这种情况下如何跟踪锁定的概念性理解。我曾经认为表锁定是一种位切换,其中表被锁定或解锁,但它似乎更像是一个带有 NOT EXISTS 的 CASE 语句;在没有解锁行的情况下,表被锁定而不是表被解锁,但其中的每一行当前都处于锁定状态。
我能够找到的所有内容都表明确实存在不同级别的锁定(表、行、页面等),但我找不到任何明确说明表为空且存在行锁的内容在插入数据时,隐含表锁。最初我预计 Select 会简单地返回 Null,但由于这不是我认为我会联系专家的行为,看看是否有人可以给我一个明确的理解。
注意:
RDBMS:SQL Server 2012
.NET Framework:4.0
核心行为:如果在插入之前表中存在记录,则两个查询都会成功,但如果在插入之前表为空,则选择会被插入阻止。
桌子:
Create Table Random(ID Int Identity, Word Varchar(50), TimeInserted DateTime)
插入查询:
Insert Random(Word, TimeInserted)
Select 'Word', GetDate()
选择查询:
Select Max(TimeInserted)
From Random
Where Word Like 'A%'