2014-02-17 84 views
3

我有每5分钟运行一次的进程A,需要在表“EventLog”中写入一些内容。这一整天都在工作,但是晚上还有另一个B进程,需要从这个表中删除大量的旧数据。该表具有数百万行(包括斑点)和许多相关表(由级联删除),因此过程B运行时间大约为45分钟。虽然进程B正在运行,但进程A出现很多死锁警告,我想摆脱这些。TransactionScope优先级(摆脱死锁情况)

简单的选项是“当进程B运行时不要运行进程A”,但必须有更好的方法。我在两个进程中都使用EntityFramework 6和TransactionScope。我没有找到如何设置优先级或类似的东西在我的进程。这可能吗?

编辑: 我忘了说,我已经在使用每一个记录删除事务,所有记录不是一个事务。在内部循环中,我创建了新的DBContext和TransactionScope,因此每个记录都有自己的事务。我的问题是删除记录仍然需要一些时间,因为相关的BLOB和其他相关表中的数据(可以说每行约5秒)。当删除过程(B)与插入过程(A)交叉时,我仍然遇到死锁情况。

+0

如果他们都有一定的时间,你能对齐他们吗?如果A需要1分钟才能完成,并且从20:00开始,那么你可以在20:03开始B? – Kuzgun

+1

B在一次交易中没有理由需要45分钟。删除可以在少于30秒的交易中以较小尺寸的循环完成。解决超时问题。 – TomTom

回答

5

交易没有优先权。死锁受害者是由数据库选择的,最常用的是“需要回滚的工作”。避免死锁的一种方法是确保您阻止而不是死锁,通过以相同顺序访问表并锁定最终级别(例如,在读取数据时采取UPDLOCK,以避免两个查询被读取锁,然后试图升级到写锁)。但最终,这是一个棘手的领域 - 需要花费45M才能完成(请告诉我这不是一次交易!)总是会引发问题。

+0

我编辑了我的帖子,是的它不是一个单一的交易。我发现如何通过TSQL设置死锁优先级,但当然这有助于设置哪个进程会失败。 Mabye当B准备好运行时,我应该首先考虑A的开始。 – AlmightyMato

1

返工过程B不会一次全部删除,而是以更小的批次从未超过1分钟。在循环中运行这些操作,直到完成所有要删除的操作。

+0

我编辑了我的帖子。我已经在使用每行一个事务,而不是一个事务。 – AlmightyMato

+0

一行30秒?这是疯狂的,即使是10 x2gb blob(这将在交易之外回收)。我会开始调试。你的服务器有多重载?什么是规格?请提醒您...我在这里看到一个严重的问题。一行cascaging到100个100 x 100mb的其他行应该在不到5秒的时间内删除。 – TomTom

+0

我不是这方面的专家,它只是一个建议值,所以可以说它像你说的那样运行2-5秒。似乎还有足够的时间与另一个(插入)事务发生冲突,因为两者都试图同时编辑表。 – AlmightyMato