Entity Framework 的 Hangfire - DbContext 并发问题

Hangfire with Entity Framework - DbContext concurrency issues

我有一个 hangfire 服务负责两个工作:

我正在使用 ASP.NET MVC (5.2.3),使用 StructureMap (4.5.1) 创建一个用于依赖注入的 IoC 容器,以及 Hangfire (1.6.19)

流程是:

这两项工作都很好,除非有多个工作同时创建电子邮件。

例如:如果前端同时触发了 10 个作业来生成电子邮件,作业将失败并显示错误:

A second operation started on this context before a previous asynchronous operation completed. Use 'await' to ensure that any asynchronous operations have completed before calling another method on this context. Any instance members are not guaranteed to be thread safe.

抛出这个错误的那一行正在使用 await,但我认为这是因为有不同的线程同时访问上下文:

var ids = await context.Objects
    .Where(x => x.id == clientId && !x.IsDeleted)
    .Select(x => x.id)
    .ToListAsync();

我已经设置了 DbContext 尝试不同的范围,TransientAlwaysUnique,但错误仍然存​​在。

此外,这并不总是发生在同一行,基本上是在相关存储库中使用上下文的任何地方——如果两个作业同时命中同一行。

作业重试,电子邮件几乎每分钟发送一封,如果有数百封电子邮件要处理和发送(这就是我的情况下的问题),这可能无法正常工作

当我使用 ContainerScoped LifeCycle 时问题已解决。


StructureMap Docs:

ContainerScoped in this case means that a registration will be built once per Container, such that the root container, any child or profile container, and every single nested container will build its own object instance

这意味着对于每个从 hangfire 中解雇的工作,都有一个新的 DataContext 实例(如果我理解正确,我可能会在更正的情况下说话)

特别是对于 Datacontext,我必须启用 MARS (Multiple Active Result Sets),这使 SQL 服务器允许在单个连接上执行多个批处理。