我似乎在 SQL Server 2008 中遗漏了一些有关锁的内容。这是我的情况:
- 开始翻译。
- 从表 A 中读取以确保找到特定行。
- 读取时,对读取的单行放置只读锁。如果没有找到,则抛出错误。
- 插入表 B,其中包含对表 A 的引用。
- 提交 tran(释放锁)。
由于各种设计限制,在这个特定实例中,我无法创建关系来为我管理此问题。所以我必须用代码来完成。
我不想对表 A 进行 XLOCK 或 UPDLOCK,因为我所在的事务只是从中读取,而不是写入。但是,显然我也不希望有任何其他内容来更新/删除引用的行。 所以我需要一个只读锁从外部角度。
我不希望出现任何幻读。显然,我不希望出现不同的行版本。
一旦 tran 提交,就可以修改表 A,因为触发器(删除后)会将表 B 中的引用清空。
这就是我所拥有的:
BEGIN TRAN
-- test
IF NOT EXISTS (
SELECT 1
FROM Table1
WITH (HOLDLOCK, ROWLOCK)
WHERE (ID = @ID)
) {throw}
{perform insert into Table2}
COMMIT TRAN
最佳答案
将事务隔离级别设置为 REPEATABLE READ在您的交易期间。在我看来,这也比使用锁定提示更可取,因为代码实现更加清晰。
由于您只读取一行,因此无需担心范围插入到您的集合中,这是可重复读取的警告。
我建议阅读本书中的“锁定和闩锁”一章Professional SQL Server 2008 Internals and Troubleshooting 。它包含对 SQL Server 中可用的各种隔离级别的精彩解释(包括代码示例),以及描述每个数据异常场景(例如幻影等)的机制。
免责声明:我不在这本书的工资单上,但我有两本,一本是硬本,另一本是 Kindle 版,这就是我买了两次的好处!
关于sql-server - SQL Server 中的只读锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4427833/