user2451412
user2451412

Reputation: 89

DbContext instance used in two places concurrently - EF - Hangfire

I'm using EF Core and Hangfire to run a recurring job. Hangfire seems to be causing the following error:

A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of DbContext. For more information on how to avoid threading issues with DbContext

And.. I'm not sure why. I register the EF context as follows:

services 
    .AddDbContext<PaymentContext>(options => options.UseNpgsql(connectionString),
    ServiceLifetime.Transient); 

And then..

app.UseHangfireDashboard();
app.UseHangfireServer();
   
RecurringJob.AddOrUpdate(() => myService.ExecuteMyJob(), Cron.Minutely);

Where myService has been injected into the Startup.Configure function, and myService contains the reference to the DbContext. Which is transient in theory, and so shouldn't be shared by the service and other places.

However the stacktrace leads here:

var plans = _context.Plan
                .Include(pp => pp.PlanItem)
                .Where(pp => pp.PolicyId == policyId)
                .ToList() // materialise query
                .OrderBy(pp => pp.PlanItem.First().Date)
                .ToList();

Upvotes: 3

Views: 1141

Answers (1)

Arsalan Valoojerdi
Arsalan Valoojerdi

Reputation: 1026

You should create scope for your dependency.

public class Job
{
    private readonly IServiceProvider _serviceProvider;
    
    public Job(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public void ExecuteJob()
    {
        using (var scope = serviceProvider.CreateScope())
        {
            var databaseContext = scope.ServiceProvider.GetRequiredService<DatabaseContext>();
            // do something
        }
    }
}

Upvotes: 1

Related Questions