在 IsolationLevel.ReadUncommitted 上发出共享锁

dsu*_*sum 10 sql-server-2008 sql-server locking isolation-level

我读到,如果我使用 IsolationLevel.ReadUncommitted,则查询不应发出任何锁。但是,当我对此进行测试时,我看到了以下锁定:

Resource_Type:HOBT
Request_Mode:S(共享)

什么是 HOBT 锁?与 HBT(堆或二叉树锁)相关的东西?

为什么我还会得到 S 锁?

在不打开隔离级别快照选项的情况下进行查询时如何避免共享锁定?

我正在 SQLServer 2008 上对此进行测试,并且快照选项设置为关闭。查询仅执行选择。

我可以看到 Sch-S 是必需的,尽管 SQL Server 似乎没有在我的锁定查询中显示它。为什么它仍然发出共享锁?根据:

设置事务隔离级别 (Transact-SQL)

在该READ UNCOMMITTED级别运行的事务不会发出共享锁,以防止其他事务修改当前事务读取的数据。

所以我有点困惑。

Mar*_*ith 13

什么是HOBT锁?

保护 B 树(索引)或没有聚集索引的表中的堆数据页的锁。

为什么我还会得到 S 锁?

这发生在堆上。例子

SET NOCOUNT ON;

DECLARE @Query nvarchar(max) = 
   N'DECLARE @C INT; 
     SELECT @C = COUNT(*) FROM master.dbo.MSreplication_options';

/*Run once so compilation out of the way*/
EXEC(@Query);

DBCC TRACEON(-1,3604,1200) WITH NO_INFOMSGS;

PRINT 'READ UNCOMMITTED';
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
EXEC(@Query);

PRINT 'READ COMMITTED';
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
EXEC(@Query);

DBCC TRACEOFF(-1,3604,1200) WITH NO_INFOMSGS;
Run Code Online (Sandbox Code Playgroud)

输出 READ UNCOMMITTED

Process 56 acquiring Sch-S lock on OBJECT: 1:1163151189:0  (class bit0 ref1) result: OK

Process 56 acquiring S lock on HOBT: 1:72057594038910976 [BULK_OPERATION] (class bit0 ref1) result: OK

Process 56 releasing lock on OBJECT: 1:1163151189:0 
Run Code Online (Sandbox Code Playgroud)

输出 READ COMMITTED

Process 56 acquiring IS lock on OBJECT: 1:1163151189:0  (class bit0 ref1) result: OK

Process 56 acquiring IS lock on PAGE: 1:1:169 (class bit0 ref1) result: OK

Process 56 releasing lock on PAGE: 1:1:169

Process 56 releasing lock on OBJECT: 1:1163151189:0 
Run Code Online (Sandbox Code Playgroud)

根据这篇引用 Paul Randal 的文章,采用这个BULK_OPERATION共享 HOBT 锁的原因是为了防止读取未格式化的页面。


Rem*_*anu 5

ReadUncommitted 隔离级别确实获取锁。模式稳定性锁可防止被查询的对象在查询执行时被更改。此锁在所有隔离级别下获取,包括快照和 read_committed_snapshot (RCSI)。从锁定模式

模式锁

数据库引擎在表数据定义语言 (DDL) 操作(例如添加列或删除表)期间使用架构修改 (Sch-M) 锁。在持有期间,Sch-M 锁会阻止对表的并发访问。这意味着 Sch-M 锁会阻止所有外部操作,直到锁被释放。

某些数据操作语言 (DML) 操作(例如表截断)使用 Sch-M 锁来防止并发操作访问受影响的表。

数据库引擎在编译和执行查询时使用架构稳定性 (Sch-S) 锁。Sch-S 锁不会阻塞任何事务锁,包括排它 (X) 锁。因此,在编译查询时,其他事务(包括对表使用 X 锁的事务)继续运行。但是,并发 DDL 操作和获取 Sch-M 锁的并发 DML 操作无法在表上执行。