从死锁中更新
本文关键字:更新 死锁 | 更新日期: 2023-09-27 18:18:10
我有一个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]
这段代码在事务中运行。两个表都有300多万条记录。聚集键在[Id]字段上,也有一些非聚集索引。
有趣的是,我手动检查,在我的特定示例中,有3+mio记录cWrh。[选项]和cStg。[选项]总是相同的,所以最后更新是不必要的。
我附上死日志图,编辑值说DB.wrh.Cars:死锁图
是的,在这个特定的例子中并发并没有真正增加任何值,但这是"重置"查询;"重新计算"查询在c#中进行一些[选项]计算,批量插入回SQL中,然后在并发模式下更新,这大大加快了速度。
如果可能的话,我只是想坚持这种并发方法,而不管任务是什么(简单重置还是CPU密集型工作)。
正如@KamranFarzami建议的那样,@Grantly的答案解决了我的问题。回答这个问题的关键在于他们。
SNAPSHOT的事务隔离级别可以防止死锁的发生。