Sql server 使用DELETE-OUTPUT-INSERT更新标识

Sql server 使用DELETE-OUTPUT-INSERT更新标识,sql-server,sql-insert,uniqueidentifier,sql-delete,database-deadlocks,Sql Server,Sql Insert,Uniqueidentifier,Sql Delete,Database Deadlocks,我需要在一个非常特定的场景中更新一个标识列(大多数情况下,标识将被单独保留)。当我确实需要更新它时,我只需要给它一个新值,因此我尝试使用DELETE+INSERT组合 目前,我有一个工作查询,如下所示: DELETE Test_Id OUTPUT DELETED.Data, DELETED.Moredata INTO Test_id WHERE Id = 13 (这只是一个示例,实际查询稍微复杂一些。) 一位同事提出了一个重要问题。她问这是否会导致僵局,因为我们在同一张

我需要在一个非常特定的场景中更新一个标识列(大多数情况下,标识将被单独保留)。当我确实需要更新它时,我只需要给它一个新值,因此我尝试使用
DELETE+INSERT
组合 目前,我有一个工作查询,如下所示:

DELETE Test_Id
OUTPUT DELETED.Data, 
       DELETED.Moredata 
INTO Test_id 
WHERE  Id = 13 
(这只是一个示例,实际查询稍微复杂一些。)
一位同事提出了一个重要问题。她问这是否会导致僵局,因为我们在同一张桌子上写和读。虽然在本例中它可以正常工作(半打行),但在现实世界中有成千上万行的场景中,这可能不起作用

这是真的吗?如果是的话,有什么办法可以预防吗

我建立了一个新的系统。

谢谢

我的第一个想法是,它可以。也许这仍然是可能的,但是在这个简化版本的声明中,很难打破僵局。您选择的是一行,该行可能会获得行级别的锁,另外,删除和插入所需的锁会很快获得

我对一个包含一百万行的表做了一些测试,在6个不同的连接上并行执行语句500万次。没有遇到任何僵局

但是添加reallive查询,一个包含索引和外键的表,您可能会有一个赢家。我有一个类似的声明,它确实导致了僵局

我遇到过类似语句的死锁错误

UPDATE A
SET x=0
OUTPUT INSERTED.ID, 'a' INTO B
因此,为了完成此语句,mssql需要为表A上的更新获取锁,为表B上的插入获取锁,并为表A获取共享(读取)锁,以验证表B必须为表A提供的外键

最后但并非最不重要的一点是,mssql决定在这个导致语句自身死锁的特定查询上使用并行性是明智的。为了解决这个问题,我只需在语句上设置“maxdop1”查询提示,以防止并行性


然而,没有明确的答案来防止死锁。正如人们常说的,mssql取决于它。您可以使用TABLOCKX表格提示获取独占。这将防止出现死锁,但由于其他原因,这可能是不可取的

好主意。如果这是一个索引键,那么即使允许(例如,对于具有序列而不是标识的列),也有可能会将相应的更新实现为delete+insert。