带有实体框架的Hangfire-DbContext并发问题

时间:2019-03-11 07:32:37

标签: c# asp.net-mvc entity-framework dbcontext hangfire

我有一个负责执行两项工作的hangfire服务:

  • 创建带有相关附件的电子邮件对象(耗时的过程)
  • 处理和发送Pending电子邮件。

我正在使用 ASP.NET MVC(5.2.3) StructureMap(4.5.1)创建用于依赖项注入的IoC容器> Hangfire(1.6.19)

流为:

  • 将触发从前端创建电子邮件的操作,在该前端创建了“即发即弃” hangfire作业,并将其以Pending状态推送到数据库中。
    • 此过程使用一些存储库对象来创建PDF格式的客户端报告(这些存储库使用DbContext从数据库中检索信息)
  • 另一项定期工作,提取所有Pending电子邮件,并使用System.Net.Mail为每封电子邮件撰写一封电子邮件。

这两个作业都可以正常工作,除非有多个作业同时创建电子邮件。

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

  

在先前的异步操作完成之前,第二个操作在此上下文上开始。使用“ await”来确保在此上下文上调用另一个方法之前,所有异步操作都已完成。不保证任何实例成员都是线程安全的。

引发此错误的行正在使用await,但我认为这是因为有不同的线程同时访问上下文:

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

我已经设置了DbContext尝试使用不同的作用域TransientAlwaysUnique,但是错误仍然存​​在。

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

作业重试,并且每分钟发送一封电子邮件,如果要处理和发送数百封电子邮件,这可能不起作用(在我的情况下,这是问题所在)

0 个答案:

没有答案