【问题标题】:Understanding locking behavior in SQL Server了解 SQL Server 中的锁定行为
【发布时间】:2023-04-11 04:23:01
【问题描述】:

我试图重现问题[1]的情况。

在桌子上,从 wiki 的“隔离(数据库系统)”[2] 中获取并填充数据,
在 SQL Server 2008 R2 SSMS 中,我执行了:

1) SSMS 的第一个选项卡(窗口)中的第一个

-- transaction isolation level in first window does not influence results (?)
-- initially I thought that second transaction in 2) runs at the level set in first window

begin transaction 
INSERT INTO users VALUES ( 3, 'Bob', 27 )
waitfor delay '00:00:22'
rollback

2) 紧接着,在第二个窗口中

-- this is what I commented/uncommented

-- set transaction isolation level SERIALIZABLE
-- set transaction isolation level READ REPEATABLE
-- set transaction isolation level READ COMMITTED
-- set transaction isolation level READ UNCOMMITTED

SELECT * FROM users --WITH(NOLOCK)

更新:
抱歉,结果已更正。

根据 2) 中设置的隔离级别,我的结果是 SELECT 返回:

  • 立即(读取未提交的插入行)

    • 对于所有带有 NOLOCK 的 SELECT 情况
    • 用于 READ UNCOMMITTED(选择带或不带 NOLOCK)
  • 正在等待事务 1) 的完成(仅当 SELECT 没有 NOLOCK)和

    • 在 READ COMMITTED 及更高(REPEATABLE READ,SERIALIZABLE)事务隔离级别

这些结果与问题中描述的情况相矛盾(并在答案中解释过?)[1]
(例如,带有 NOCHECK 的 SELECT 正在等待 1) 的完成)等。

如何解释我的结果和 [1]?


更新2:
这个问题实际上是我的问题 [3] 的子问题(或未回答的结果)。

引用:
[1]
解释 SQL Server 中的锁定行为
Explain locking behavior in SQL Server
[2]
“隔离(数据库系统)”
请添加尾随)链接。我无法设法将它保存在链接中! http://en.wikipedia.org/wiki/Isolation_(database_systems)
[3]
NOLOCK 是 SQL Server 2005 中 SELECT 语句的默认值吗?
Is NOLOCK the default for SELECT statements in SQL Server 2005?

【问题讨论】:

  • 插入事务的隔离级别根本不会影响第二个事务看到的内容。您确定您的第二笔交易没有在READ UNCOMMITTED 级别下运行吗?

标签: sql-server tsql transactions locking isolation-level


【解决方案1】:

有一个有用的MSDN 链接,她谈论 SQL 2008 中的锁定提示。也许在您的示例中,它是 SQL Server 2008 不喜欢您的表锁的情况?

(以下链接中的以下 sn-p 讨论了 SQL Server 2008 可能引入的锁)

如以下示例所示,如果事务隔离级别设置为 SERIALIZABLE,并且表级锁定提示 NOLOCK 与 SELECT 语句一起使用,则通常用于维护 可序列化事务的键范围锁不会采取

CopyUSE AdventureWorks2008R2;
GO
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
GO
BEGIN TRANSACTION;
GO
SELECT Title
    FROM HumanResources.Employee WITH (NOLOCK);
GO

-- Get information about the locks held by 
-- the transaction.
SELECT  
        resource_type, 
        resource_subtype, 
        request_mode
    FROM sys.dm_tran_locks
    WHERE request_session_id = @@spid;

-- End the transaction.
ROLLBACK;
GO

唯一引用 HumanResources.Employee 的锁是架构稳定性(Sch-S) 锁。在这种情况下,不再保证可串行化

在 SQL Server 2008 中,ALTER TABLE 的 LOCK_ESCALATION 选项可以不赞成表锁,并在分区表上启用 HoBT 锁。此选项不是锁定提示,但可以但用于减少锁定升级。如需更多信息,请参阅ALTER TABLE (Transact-SQL)

【讨论】:

  • 这只有在原始交易执行SELECT时才有意义
  • @Martin - 谢谢,我自己不确定,但仍然觉得值得发帖。
  • 谢谢!我淹没在这方面的矛盾讨论中,只找到了其他 RDBMS(Oracle、PostGreSQL 等)中锁定描述的参考。现在有了关键短语“(Sch-S)锁定”,我在搜索中走上了正轨。 WTF,相同的锁在描述相同概念的不同 DBMS 中的调用方式不同...
  • @vgv8 - np 很高兴这篇文章有帮助。
【解决方案2】:

第二个查询中的提示覆盖事务隔离级别。
SELECT ... WITH (NOLOCK)SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; SELECT ... 基本相同。

对于任何其他隔离级别,锁都会被兑现,因此第二个事务会一直等待,直到第一个事务释放锁。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-29
    • 1970-01-01
    • 2022-01-11
    相关资源
    最近更新 更多