我有这个SQL更新查询:
UPDATE table1
SET table1.field1 = 1
WHERE table1.id NOT IN (SELECT table2.table1id FROM table2);
应用程序的其他部分可以向table2添加记录,使用字段table1id引用table1。
这里的目标是从table1中删除未被table2引用的记录。
SQL Server是否会使用此类查询自动锁定table2,以便在执行此查询时无法将新记录添加到table2?
我也考虑过:
UPDATE table1
SET field1 = 1
WHERE 0 = (SELECT COUNT(*) FROM table2 WHERE table1.id = table2.table1id);
这似乎更安全,但速度要慢得多(因为在table1的每一行上都会调用SELECT,而不是只为NOT IN调用一次)
答案 0 :(得分:5)
不,本身并不安全。子查询将获取锁并立即释放它们,允许在table2上进行并发更新/插入/删除。此外,运行此查询的多个事务可能会尝试修改table1中的相同行,即使table2稳定,可能会相互死锁。
您的第二个查询同样不安全。
很难正确地获得这些查询。对于某些查询,您可以使用XLOCK提示,但在您的情况下,您对缺少键感兴趣,因此它无济于事。唯一100%安全的替代TABLOCKX提示,但这是一个将杀死所有并发性的大锤。
最终,你必须回到退回,并问自己操作的商业含义。
答案 1 :(得分:0)
不,它不会。锁将尽快释放。 table2中的记录将暂时锁定,以便您获取某个时刻的记录,并根据该时刻,您的记录将从table1中“删除”。
我认为您的目标是确保在table1之前将记录插入table2。