我似乎在SQL Server 2008中遗漏了一些错误。这是我的方案:
由于各种设计限制,在这个特定的实例中,我无法创建一个关系来为我管理这个。所以我必须用代码来做。
我不想XLOCK或UPDLOCK表A,因为我所处的事务只是从中读取,而不是写入。但是,显然我不想要任何其他内容来更新/删除引用的行。 所以我需要从外部角度看的只读锁。
我不希望任何幻像读取成为可能。我显然不希望有不同的行版本。
一旦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
答案 0 :(得分:1)
在交易期间将交易隔离级别设置为REPEATABLE READ。在我看来,这也是使用锁定HINTS的首选,因为代码实现的清晰度会提高。
当您只阅读一行时,您无需担心范围插入到您的集合中,这是一个可重复阅读的警告。
我建议阅读本书Professional SQL Server 2008 Internals and Troubleshooting中的“锁定和锁存”一章。它包含SQL Server中可用的各种隔离级别的优秀解释,包括代码示例,以及描述每个数据异常场景的机制,例如Phantoms等。
免责声明:我不在这个职位的工资单上,但我有两份副本,一份是硬件,另一份是kindle版本,这就是我买两次的好处!