C# SQL Server-使用UPDLOCK提示进行查询时发生死锁

C# SQL Server-使用UPDLOCK提示进行查询时发生死锁,c#,sql-server,deadlock,C#,Sql Server,Deadlock,我有一个C代码,它使用EntityFramework执行一系列SQL语句: using (var context = new MyDbContext()) { context.Database.ExecuteSqlCommand(preparedQuery.QueryText); } 该查询用于使用不断切分的数据更新表,并使用可序列化事务隔离级别和UPDLOCK table提示来避免争用条件问题。preparedQuery.QueryText是一个如下所示的字符串: SET TRANS

我有一个C代码,它使用EntityFramework执行一系列SQL语句:

using (var context = new MyDbContext())
{
    context.Database.ExecuteSqlCommand(preparedQuery.QueryText);
}
该查询用于使用不断切分的数据更新表,并使用可序列化事务隔离级别和UPDLOCK table提示来避免争用条件问题。preparedQuery.QueryText是一个如下所示的字符串:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRAN T11;
DECLARE @Flag int;
SET @Flag = (SELECT Count(*)  FROM MyTable  WITH (UPDLOCK) WHERE Field1 = '1' AND Field2 = '2')
IF (@Flag > 0) 
BEGIN
    UPDATE MyTable SET Filed3 = '3'  WHERE Field1 = '1' AND Field2 = '2'
END
C方法不时抛出SqlException,并显示以下消息:

事务处理ID 202在具有的锁资源上死锁 另一个进程和已被选为死锁牺牲品。重新运行 交易


一个在开始时有UPDLOCK表提示的SQL可序列化事务怎么可能死锁?事务的第一个查询获得数据的更新锁。什么类型的其他事务可能会因此查询而死锁?

分析实际死锁并查看。永远不要试图猜测僵局可能是什么——你可能猜错了。即使您以独占方式锁定所有数据,死锁也是可能的:只需要两个查询尝试以不同的顺序获取这些独占锁。请注意:顺便说一下,SELECT COUNT*不一定会对所有数据进行锁定。如果Field1/Field2上有索引,则仅扫描该索引即可满足计数*的要求,但更新始终需要触摸聚集索引。您最好将此应用程序滚动到单个更新中。。。而不是先选择COUNT*first。是的,您也可以在那里使用UPDLOCK,尽管它可能看起来是多余的,但实际上并非如此——更新有多个阶段。但实际上,首先要分析死锁。