Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从死锁更新_C#_Sql Server_Multithreading_Tsql_Deadlock - Fatal编程技术网

C# 从死锁更新

C# 从死锁更新,c#,sql-server,multithreading,tsql,deadlock,C#,Sql Server,Multithreading,Tsql,Deadlock,我有一个C#/.NET应用程序,它在多个线程(即并发6个线程)中尝试执行以下更新: UPDATE cWrh SET [Options] = cStg.[Options] -- byte array FROM [wrh].[Cars] cWrh INNER JOIN [stg].[Cars] cStg ON cWrh.[Id] = cStg.[Id] AND cWrh.[Manufacturer_Id] = @ManufactuerId

我有一个C#/.NET应用程序,它在多个线程(即并发6个线程)中尝试执行以下更新:

UPDATE cWrh SET
   [Options] = cStg.[Options] -- byte array
FROM
   [wrh].[Cars] cWrh
      INNER JOIN [stg].[Cars] cStg ON
         cWrh.[Id] = cStg.[Id]
         AND cWrh.[Manufacturer_Id] = @ManufactuerId -- each thread gets different id here
         AND cWrh.[Options] <> cStg.[Options]
更新cWrh集合
[Options]=cStg.[Options]--字节数组
从…起
[wrh][Cars]cWrh
内部连接[stg].[Cars]cStg打开
cWrh.[Id]=cStg.[Id]
和cWrh。[Manufacturer\u Id]=@manufactureuid——每个线程在这里获得不同的Id
和cWrh。[选项]cStg。[选项]
这是在事务中运行的一段代码。两个表都有超过3百万条记录。聚集键位于[Id]字段上,还有一些非聚集索引

有趣的是,我手动检查了,在我的特定示例中,3+mio记录cWrh.[Options]和cStg.[Options]总是相同的,因此最终不需要更新

我正在附上死区记录图,修改后的值为DB.wrh.Cars:

是的,在这个特定的示例中,并发并没有真正增加任何值,但这是“重置”查询;“重新计算”查询在C#中执行一些[Options]计算,批量插入到SQL中,并在以后以并发模式更新,大大加快了速度

如果可能的话,不管任务是什么(简单重置还是CPU密集型工作),我都希望坚持这种并行方法


任何关于如何解决僵局的建议都将不胜感激。

正如@KamranFarzami所建议的那样,@Grantly的回答解决了我的问题。回答这个问题的关键在于他们


快照的事务隔离级别可以防止死锁发生。

不知道,但是想知道
readpass
提示是否合适??由于每个线程都有一个不同的
@manufactureId
,因此它们不应该互相践踏(对吗?),也应该检查
行锁是否有用。再说一次,我真的不知道,所以请恕我直言。这个问题的答案可能会有所帮助。它建议使用隔离快照@David你是对的,每个线程的ManufacturerId总是唯一的。我尝试了readpas和rowlock,但仍然得到了支持deadlocks@KamranFarzami:谢谢你提到隔离快照。他们似乎是正确的选择。但是,我不能一直使用它们,因为我的一些事务(上面提到的“重置”事务除外)处理临时表,并在这些临时表之上创建索引;这似乎是一个已知的限制,因为无论是在本地临时表上还是在DB表上,都无法在具有snaphot隔离级别的事务中执行DDL