我有一个每5分钟运行一次的进程A,需要在表“EventLog”中写一些东西。这整天都在工作,但是在晚上还有另一个进程B开始需要从该表中删除大量旧数据。该表有数百万行(包括blob)和许多相关表(通过级联删除),因此进程B最多运行约45分钟。当进程B运行时,我得到了很多进程A的死锁警告,我想摆脱这些。
简单的选项是“当进程B运行时不要运行进程A”,但必须有更好的方法。我在两个进程中都使用EntityFramework 6和TransactionScope。我没有找到如何在我的进程中设置优先级或类似的东西。这可能吗?
修改 我忘了说我已经在每条记录使用一个删除事务,而不是所有记录都使用一个事务。在内部循环中,我创建了新的DBContext和TransactionScope,因此每条记录都有自己的事务。我的问题是删除记录仍然需要一些时间,因为相关的BLOB和其他相关表中的数据(假设每行大约5秒)。当删除进程(B)与插入进程(A)交叉时,我仍然遇到死锁情况。
答案 0 :(得分:5)
交易没有优先权。死锁受害者是由数据库选择的,最常见的是使用诸如“回滚所需的工作”之类的东西。避免死锁的一种方法是确保阻塞而不是死锁,通过以相同的顺序访问表,并在最终级别获取锁(例如,在读取数据时取UPDLOCK
,以避免两个查询获取读锁定,然后一个尝试升级到写锁定。但最终,这是一个棘手的领域 - 需要45M才能完成(请告诉我这不是一笔交易!)总会引起问题。
答案 1 :(得分:1)
返工流程B不能一次删除所有内容,但是从不需要超过1分钟的小批量删除。在循环中运行它们直到完成所有要删除的操作。