You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server READ_COMMITTED_SNAPSHOT隔离级别共享锁未阻塞问题

问题解析:READ_COMMITTED_SNAPSHOT=OFF时SELECT未阻塞UPDATE的原因

既不是文档错误,也不是你完全理解错,而是你忽略了默认READ_COMMITTED隔离级别下共享锁的释放时机细节:

  • 默认(RCSI OFF)的READ_COMMITTED隔离级别中,共享锁是语句级释放,而非事务级。也就是说,当SELECT语句执行完成后,对应的共享锁就会被立即释放,不会持有到整个事务结束。
  • 微软文档里的“阻止其他事务在当前事务读取时修改行”,这里的“读取时”指的是SELECT语句正在执行的过程中(比如正在读取目标行的瞬间),而非整个事务存续期间。

你的测试场景分析

你在窗口1的事务中执行SELECT后,语句很快执行完成,共享锁随即释放,所以窗口2的UPDATE能立即成功,不会被阻塞。如果想复现“SELECT阻塞UPDATE”的场景,需要让SELECT的共享锁持有到事务结束,这时候需要显式添加锁提示:

测试复现步骤(阻塞场景)

窗口1执行:

BEGIN TRANSACTION;
-- 用HOLDLOCK提示让共享锁持有到事务结束
SELECT * FROM Users WHERE Id = 1 WITH (HOLDLOCK);
WAITFOR DELAY '00:00:10'; -- 保持事务打开10秒
COMMIT TRANSACTION;

窗口2在窗口1执行完SELECT后立刻执行:

BEGIN TRANSACTION;
UPDATE Users SET Reputation = Reputation + 1 WHERE Id = 1;
COMMIT TRANSACTION;

此时窗口2的UPDATE会被阻塞,直到窗口1提交/回滚事务,这才符合你最初预期的锁行为。

补充说明

默认READ_COMMITTED的锁行为是为了平衡一致性和并发度:语句级释放锁可以减少锁持有时间,提升系统并发能力;如果需要事务级的锁持有,就要用更高的隔离级别(比如SERIALIZABLE)或显式锁提示。

内容的提问来源于stack exchange,提问作者Dhanuka Jayasinghe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 23:45:23