C# 从死锁更新
我有一个C#/.NET应用程序,它在多个线程(即并发6个线程)中尝试执行以下更新: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
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