use*_*erx 1 sql t-sql sql-server
我有这个SQL更新查询:
UPDATE table1
SET table1.field1 = 1
WHERE table1.id NOT IN (SELECT table2.table1id FROM table2);
Run Code Online (Sandbox Code Playgroud)
应用程序的其他部分可以向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);
Run Code Online (Sandbox Code Playgroud)
这看起来可能更安全,但速度要慢得多(因为在table1的每一行上都会调用SELECT而不是只为NOT IN调用一行)
不,本身并不安全.子查询将获取锁并立即释放它们,允许在table2上进行并发更新/插入/删除.此外,运行此查询的多个事务可能会尝试修改table1中的相同行,即使table2稳定,也可能相互死锁.
你的第二个查询同样不安全.
很难让这些问题得到正确的解决.对于某些查询,您可以使用XLOCK提示,但在您的情况下,您对丢失的键感兴趣,因此它无济于事.唯一100%安全的替代TABLOCKX提示,但这是一个将杀死所有并发性的大锤.
最终,你必须回到退回,并问自己操作的商业含义.