2
我有一个C#/ NET应用程序,在多个线程中(即同时,6个线程),尝试执行以下更新:UPDATE FROM死锁
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]
这一段代码在事务中运行。这两个表都有3 + mio记录。集群键在[Id]字段上,也有一些非聚集索引。
有趣的是,我手动检查,并在我的特殊示例中使用3 + mio记录cWrh。[Options]和cStg。[Options]始终相同,因此最终不需要更新。
我附加了deadlog图,删节值说DB.wrh.Cars: Deadlock graph
是的,在这个特殊的例子并发是不是真的增加任何价值,但这是“复位”查询;在C#中执行一些[Options]计算的“重新计算”查询,批量插入SQL并稍后以并发模式更新,显着加速了这一事情。
如果可能的话,我只想坚持这种并发方法,无论任务如何(简单复位与CPU密集型工作)。
任何建议如何解决僵局是值得赞赏的。
不知道,但想知道'readpast'提示可能是合适的?由于每个线程都有不同的'@ ManufactuerId',它们*不应该*彼此践踏(对吗?)也许值得检查'rowlock'是否有帮助。再一次,我真的不知道,所以拿一点盐来吧。 – David
这个问题的答案可能会有所帮助。它建议使用隔离快照。 http://stackoverflow.com/questions/27206244/sql-server-prevent-lost-update-and-deadlocks –
@大卫你是对的,ManufacturerId总是唯一的每个线程。我尝试使用readpas以及rowlock,但仍然出现死锁 – mpfx