title: Multiple Concurrency access to DbContext in Webapi
body: <p>I have a WebApi that that uses EFCore2.0 and 2 client trying to access to an action method at a same time ...
  Everything is working fine with one client. But when 2 or more trying to access to a one particular action method at a same time, I got this error at Microsoft.EntityFrameworkCore :</p>
  
  <blockquote>
    <p>A second operation started on this context before a previous operation
    completed. Any instance members are not guaranteed to be thread safe</p>
  </blockquote>
  
  <p>I used DI and repository for WebApi. I defined Scope for IUnitOfWork,I defined Transient, but nothing is worked.</p>
  
  <p>This is my startup :</p>
  
  <pre class="lang-cs prettyprint-override"><code>....
  services.AddSingleton(provider =&gt; Configuration);
              services.AddSingleton&lt;IHttpContextAccessor, HttpContextAccessor&gt;();
              services.AddScoped&lt;IUnitOfWork, ApplicationDbContext&gt;();
              services.AddTransient&lt;IRoleService, RoleService&gt;();
              services.AddTransient&lt;ISecurityService, SecurityService&gt;();
              services.AddTransient&lt;IDbInitializerService, DbInitializerService&gt;();
              services.AddTransient&lt;ITokenStoreService, TokenStoreService&gt;();
              services.AddTransient&lt;ITokenValidatorService, TokenValidatorService&gt;();
              services.AddTransient&lt;ICookieValidatorService, CookieValidatorService&gt;();
              services.AddTransient&lt;IRequestRepository, RequestRepository&gt;();
              services.AddDbContextPool&lt;ApplicationDbContext&gt;(options =&gt;
              {
                  options.UseSqlServer(
                      Configuration["ConnectionStrings:ApplicationDbContextConnection"].ToString(),
                      serverDbContextOptionsBuilder =&gt;
                      {
                          var minutes = (int)TimeSpan.FromMinutes(3).TotalSeconds;
                          serverDbContextOptionsBuilder.CommandTimeout(minutes);
                          serverDbContextOptionsBuilder.EnableRetryOnFailure();
                      });
              });
  ....
  </code></pre>
  
  <p>This is my DbContext:</p>
  
  <pre class="lang-cs prettyprint-override"><code>namespace Eela.Data
  {
  
      public class
          ApplicationDbContextFactory : IDesignTimeDbContextFactory&lt;ApplicationDbContext&gt;
      {
  
  
          public ApplicationDbContext CreateDbContext(string[] args)
          {
              var services = new ServiceCollection();
              services.AddOptions();
              services.AddScoped&lt;IHostingEnvironment, CustomHostingEnvironment&gt;();
              services.AddSingleton&lt;ILoggerFactory, LoggerFactory&gt;();
              var serviceProvider = services.BuildServiceProvider();
              var loggerFactory = serviceProvider.GetRequiredService&lt;ILoggerFactory&gt;();
              var logger = loggerFactory.CreateLogger&lt;ConfigProvider&gt;();
              var hostingEnvironment = serviceProvider.GetRequiredService&lt;IHostingEnvironment&gt;();
              Console.WriteLine($"Using `{hostingEnvironment.ContentRootPath}` as the ContentRootPath");
              var configuration = new ConfigurationBuilder()
                  .SetBasePath(basePath: hostingEnvironment.ContentRootPath)
                  .AddJsonFile(path: "appsettings.json", reloadOnChange: true, optional: false)
                  .AddEncryptedProvider(hostingEnvironment: hostingEnvironment, logger: logger)
                  .AddJsonFile(path: $"appsettings.{hostingEnvironment.EnvironmentName}.json", optional: true)
                  .Build();            
              var builder = new DbContextOptionsBuilder&lt;ApplicationDbContext&gt;();
              var connectionString = configuration["ConnectionStrings:ApplicationDbContextConnection"];
              var useInMemoryDatabase = configuration[key: "UseInMemoryDatabase"].Equals(value: "true",
                  comparisonType: StringComparison.OrdinalIgnoreCase);
              if (useInMemoryDatabase)
                  builder.UseInMemoryDatabase("MyDatabase");
              else
              builder.UseSqlServer(connectionString);
              builder.ConfigureWarnings(warnings =&gt; warnings.Log(CoreEventId.IncludeIgnoredWarning));
              return new ApplicationDbContext(builder.Options);
          }
      }
  
      public class ApplicationDbContext : DbContext, IUnitOfWork
      {
  
          public ApplicationDbContext(DbContextOptions options) : base(options)
          { }
          protected override void OnModelCreating(ModelBuilder model)
          {
              base.OnModelCreating(model);
  
              model.Entity&lt;Person&gt;().Property(p =&gt; p.PersonId).ValueGeneratedOnAdd();
              model.Entity&lt;Person&gt;()
                  .HasDiscriminator&lt;int&gt;(name: "Type")
                  .HasValue&lt;WorkerTaxi&gt;(value: Convert.ToInt32(value: AccountType.TaxiWorker))
                  .HasValue&lt;User&gt;(value: Convert.ToInt32(value: AccountType.User))
                  .HasValue&lt;Reseller&gt;(value: Convert.ToInt32(value: AccountType.Reseller));
  
              model.Entity&lt;Log&gt;().Property(p =&gt; p.Id).ValueGeneratedOnAdd();
              model.Entity&lt;Log&gt;()
                  .HasDiscriminator&lt;int&gt;(name: "Type")
                  .HasValue&lt;LogRequest&gt;(value: Convert.ToInt32(value: LogLevel.Information))
                  .HasValue&lt;LogError&gt;(value: Convert.ToInt32(value: LogLevel.Error));
  
              model.Entity&lt;Request&gt;().Property(p =&gt; p.RequestId).ValueGeneratedOnAdd();
              model.Entity&lt;Request&gt;()
                  .HasDiscriminator&lt;int&gt;(name: "Type")
                  .HasValue&lt;RequestTaxi&gt;(value: Convert.ToInt32(value: RequestType.TaxiRequester));
  
              model.Entity&lt;ApplicationUsers&gt;().Property(p =&gt; p.Id).ValueGeneratedOnAdd();
              model.Entity&lt;Role&gt;().Property(p =&gt; p.RoleId).ValueGeneratedOnAdd();
              model.Entity&lt;Car&gt;().Property(p =&gt; p.CarId).ValueGeneratedOnAdd();
              model.Entity&lt;Address&gt;().Property(p =&gt; p.AddressId).ValueGeneratedOnAdd();
              model.Entity&lt;Organization&gt;().Property(p =&gt; p.OrganizationId).ValueGeneratedOnAdd();
              model.Entity&lt;Credit&gt;().Property(p =&gt; p.CreditId).ValueGeneratedOnAdd();
              model.Entity&lt;StablePrice&gt;().Property(p =&gt; p.StablePriceId).ValueGeneratedOnAdd();
              model.Entity&lt;Package&gt;().Property(p =&gt; p.PackageId).ValueGeneratedOnAdd();
              model.Entity&lt;Rating&gt;().Property(p =&gt; p.RatingId).ValueGeneratedOnAdd();
              model.Entity&lt;City&gt;().Property(p =&gt; p.CityId).ValueGeneratedOnAdd();
              model.Entity&lt;SpecialAddress&gt;().Property(p =&gt; p.SpecialAddressId).ValueGeneratedOnAdd();
              model.Entity&lt;UserToken&gt;().Property(p =&gt; p.Id).ValueGeneratedOnAdd();
              model.Entity&lt;PersonRequest&gt;(entity =&gt;
              {
                  entity.HasKey(e =&gt; new {e.RequestId, e.PersonId})
                      .HasName(name: "PK_dbo.PersonRequest");
  
                  entity.HasIndex(e =&gt; e.RequestId)
                      .HasName(name: "IX_RequestId");
  
                  entity.HasIndex(e =&gt; e.PersonId)
                      .HasName(name: "IX_PersonId");
              });
              model.Entity&lt;PackageReseller&gt;(entity =&gt;
              {
                  entity.HasKey(e =&gt; new { e.PackageId, e.ResellerId })
                      .HasName(name: "PK_dbo.PackageReseller");
  
                  entity.HasIndex(e =&gt; e.PackageId)
                      .HasName(name: "IX_PackageId");
  
                  entity.HasIndex(e =&gt; e.ResellerId)
                      .HasName(name: "IX_ResellerId");
              });
              model.Entity&lt;UserRole&gt;(entity =&gt;
              {
                  entity.HasKey(e =&gt; new { e.ApplicationUserId, e.RoleId })
                      .HasName(name: "PK_dbo.UserRole");
  
                  entity.HasIndex(e =&gt; e.ApplicationUserId)
                      .HasName(name: "IX_ApplicationUserId");
  
                  entity.HasIndex(e =&gt; e.RoleId)
                      .HasName(name: "IX_RoleId");
              });
          }
          public virtual DbSet&lt;ApplicationUsers&gt; ApplicationUsers { get; set; }
          public virtual DbSet&lt;Role&gt; Role { get; set; }
          public virtual DbSet&lt;UserRole&gt; UserRole { get; set; }
          public virtual DbSet&lt;UserToken&gt; UserToken { get; set; }
  
          public virtual DbSet&lt;Address&gt; Address { get; set; }
          public virtual DbSet&lt;Credit&gt; Credit { get; set; }
          public virtual DbSet&lt;Organization&gt; Organization { get; set; }
          public virtual DbSet&lt;City&gt; City { get; set; }
          public virtual DbSet&lt;StablePrice&gt; StablePrice { get; set; }
          public virtual DbSet&lt;PersonRequest&gt; PersonRequest { get; set; }
          public virtual DbSet&lt;Discount&gt; Discount { get; set; }
          public virtual DbSet&lt;Rating&gt; Rating { get; set; }
          public virtual DbSet&lt;SpecialAddress&gt; SpecialAddress { get; set; }
  
  
          public void AddRange&lt;TEntity&gt;(IEnumerable&lt;TEntity&gt; entities) where TEntity : class
          {
              Set&lt;TEntity&gt;().AddRange(entities: entities);
          }
  
          public void RemoveRange&lt;TEntity&gt;(IEnumerable&lt;TEntity&gt; entities) where TEntity : class
          {
              Set&lt;TEntity&gt;().RemoveRange(entities: entities);
          }
  
          public void MarkAsChanged&lt;TEntity&gt;(TEntity entity) where TEntity : class
          {
              Entry(entity: entity).State = EntityState.Modified; // Or use ---&gt; this.Update(entity);
          }
  
          public void ExecuteSqlCommand(string query)
          {
              Database.ExecuteSqlCommand(sql: query);
          }
  
          public void ExecuteSqlCommand(string query, params object[] parameters)
          {
              Database.ExecuteSqlCommand(sql: query, parameters: parameters);
          }
  
          public int SaveAllChanges()
          {
              return SaveChanges();
          }
  
          public Task&lt;int&gt; SaveAllChangesAsync()
          {
              return SaveChangesAsync();
          }
      }
  }
  </code></pre>
  
  <p>This my IUnitOfWork:</p>
  
  <pre class="lang-cs prettyprint-override"><code>namespace Eela.Data
  {
      public interface IUnitOfWork : IDisposable
      {
          DbSet&lt;TEntity&gt; Set&lt;TEntity&gt;() where TEntity : class;
  
          void AddRange&lt;TEntity&gt;(IEnumerable&lt;TEntity&gt; entities) where TEntity : class;
          void RemoveRange&lt;TEntity&gt;(IEnumerable&lt;TEntity&gt; entities) where TEntity : class;
  
          EntityEntry&lt;TEntity&gt; Entry&lt;TEntity&gt;(TEntity entity) where TEntity : class;
          void MarkAsChanged&lt;TEntity&gt;(TEntity entity) where TEntity : class;
  
          void ExecuteSqlCommand(string query);
          void ExecuteSqlCommand(string query, params object[] parameters);
  
          int SaveAllChanges();
          Task&lt;int&gt; SaveAllChangesAsync();
  
          int SaveChanges(bool acceptAllChangesOnSuccess);
          int SaveChanges();
          Task&lt;int&gt; SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = new CancellationToken());
          Task&lt;int&gt; SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken());
      }
  }
  </code></pre>
  
  <p>This is one of my repositories :</p>
  
  <pre class="lang-cs prettyprint-override"><code>public class RequestRepository : IRequestRepository
     {
         private readonly IMapper _mapper;
         private readonly IUnitOfWork _unitOfWork;
         private readonly DbSet&lt;Request&gt; _request;
         private readonly DbSet&lt;Person&gt; _person;
         private readonly DbSet&lt;PersonRequest&gt; _personRequest;
         public RequestRepository(IMapper mapper, IUnitOfWork unitOfWork)
         {
             _mapper = mapper;
             _unitOfWork = unitOfWork;
             _request = _unitOfWork.Set&lt;Request&gt;();
             _person = _unitOfWork.Set&lt;Person&gt;();
             _personRequest = _unitOfWork.Set&lt;PersonRequest&gt;();
         }
       public async Task&lt;DetailPageViewModel&gt; GetRequestAsync(string requestId)
         {
             var request = await (from x in _request
                 where x.RequestId == Guid.Parse(requestId)
                 from y in x.PersonsRequests
                 where y.Person is User
                 select new DetailPageViewModel
                 {
                     RequestId = x.RequestId.ToString(),
                     CustomerName = y.Person.LastName,
                     SourceAddress = ((RequestTaxi) x).SourceAddress,
                     DestinationAddress = ((RequestTaxi) x).DestinationAddress,
                     DestinationLat = x.DestinationLat,
                     DestinationLon = x.DestinationLon,
                     EstimateDistance = ((RequestTaxi) x).Distance.ToString(CultureInfo.InvariantCulture),
                     EstimateDriverPrice = x.Price.ToString(),
                     EstimatePassengerPrice = x.PaymentType == PaymentType.Cash ? x.Price.ToString() : "0",
                     SourceLat = ((RequestTaxi) x).SourceLat,
                     SourceLon = ((RequestTaxi) x).SourceLon
                 }).FirstOrDefaultAsync();
  
             return
                 _mapper.Map&lt;DetailPageViewModel&gt;(
                     source: request);
         }
         .....
  </code></pre>
  
  <p>And finally, this is one of my controller :</p>
  
  <pre class="lang-cs prettyprint-override"><code>public class DetailPageController:Controller
     {
         private readonly IPersonRequestRepository _personRequest;
         private readonly IRequestRepository _request;
         private readonly IApplicationUsersRepository _appUser;
         private readonly IStablePriceRepository _stablePrice;
         private readonly ILogRepository _log;
         private readonly ICreditRepository _credit;
         private readonly INotificationService _notification;
         private readonly IPasswordGenerator _charecterGenerator;
  
         public DetailPageController(IPersonRequestRepository personRequest,ICreditRepository credit,
             ILogRepository log,IStablePriceRepository stablePrice,IApplicationUsersRepository appUser,
             IRequestRepository request,INotificationService notification,IPasswordGenerator charecterGenerator)
         {
             _personRequest = personRequest;
             _credit = credit;
             _log = log;
             _stablePrice = stablePrice;
             _appUser = appUser;
             _request = request;
             _notification = notification;
             _charecterGenerator = charecterGenerator;
         }
  
         [HttpPost]
         [ActionName("GetRequest")]
         public async Task&lt;ActionResult&gt; GetRequest([FromBody]string model)
         {
             var requestId = model;
             return Json(data: await _request.GetRequestAsync(requestId));
         }
  </code></pre>
  
  <p>RequestLoggingMiddleware.cs :</p>
  
  <pre class="lang-cs prettyprint-override"><code>public class RequestLoggingMiddleware
      {
          private readonly RequestDelegate _next;
          private readonly ILogger&lt;RequestLoggingMiddleware&gt; _logger;
          private readonly ILogRepository _logRepository;
          private readonly IConfigurationRoot _configuration;
  
          public RequestLoggingMiddleware(RequestDelegate next, ILogger&lt;RequestLoggingMiddleware&gt; logger,
              ILogRepository logRepository,IConfigurationRoot configuration)
          {
              _next = next;
              _logger = logger;
              _logRepository = logRepository;
              _configuration = configuration;
          }
  
          public async Task&lt;OperationResult&gt; Invoke(HttpContext context)
          {
              using (MemoryStream requestBodyStream = new MemoryStream())
              {
                  using (MemoryStream responseBodyStream = new MemoryStream())
                  {
                      Stream originalRequestBody = context.Request.Body;
                      context.Request.EnableRewind();
                      Stream originalResponseBody = context.Response.Body;
  
                      OperationResult op= new OperationResult();
                      try
                      {
                          await context.Request.Body.CopyToAsync(requestBodyStream);
                          requestBodyStream.Seek(0, SeekOrigin.Begin);
  
                          string requestBodyText = new StreamReader(requestBodyStream).ReadToEnd();
  
                          requestBodyStream.Seek(0, SeekOrigin.Begin);
                          context.Request.Body = requestBodyStream;
  
                          string responseBody = "";
  
  
                          context.Response.Body = responseBodyStream;
                          Stopwatch watch = Stopwatch.StartNew();
                          await _next(context);
                          watch.Stop();
  
                          responseBodyStream.Seek(0, SeekOrigin.Begin);
                          responseBody = new StreamReader(responseBodyStream).ReadToEnd();
                          var log = new LogRequestViewModel
                          {
                              Host= context.Request.Host.Host,
                              Path= context.Request.Path,
                              QueryString= context.Request.QueryString.ToString(),
                              ClientIp= context.Connection.RemoteIpAddress.MapToIPv4(),
                              Date= DateTime.Now.ToString(CultureInfo.InvariantCulture),
                              Duration= watch.ElapsedMilliseconds,
                              Method= context.Request.Method,
                              RequestContentLength= context.Request.ContentLength,
                              RequestContentType= context.Request.ContentType,
                              Application= GetType().Namespace,
                              User= context.User.Claims
                                  .FirstOrDefault(x =&gt; x.Type == _configuration["UserIdType"])?.Value,
                              Headers= string.Join(",", context.Request.Headers.Select(he =&gt; he.Key + ":[" + he.Value + "]").ToList()),
                              RequestBodyText= requestBodyText,
                              ResponseBodyText = responseBody
  
                          };
                          var result = await _logRepository.SaveRequestLogAsync(log);
                          if (!result.Success)
                          {
                              op.Success = false;
                              op.AddMessage("Couldn't add request log to database");
                              _logger.LogError(message: result.MessageList.FirstOrDefault());
                              var ex = new Exception(message: result.MessageList.FirstOrDefault());
                              await _logRepository.SaveErrorLogAsync(exception: ex);
                          }
                          responseBodyStream.Seek(0, SeekOrigin.Begin);
  
                          await responseBodyStream.CopyToAsync(originalResponseBody);
                      }
                      catch (Exception ex)
                      {
                          _logger.LogError(message: ex.Message);
                          await _logRepository.SaveErrorLogAsync(exception: ex);
                          byte[] data = System.Text.Encoding.UTF8.GetBytes("Unhandled Error occured, the error has been logged and the persons concerned are notified!! Please, try again in a while.");
                          originalResponseBody.Write(data, 0, data.Length);
                          op.Success = false;
                          op.AddMessage(ex.Message);
                      }
                      finally
                      {
                          context.Request.Body = originalRequestBody;
                          context.Response.Body = originalResponseBody;
  
                      }
                      const string logTemplate = @"
                          Client IP: {clientIP}
                          Request path: {requestPath}
                          Request content type: {requestContentType}
                          Request content length: {requestContentLength}
                          Start time: {startTime}
                          Duration: {duration}";
                      _logger.LogInformation(logTemplate,
                          context.Connection.RemoteIpAddress.ToString(),
                          context.Request.Path,
                          context.Request.ContentType,
                          context.Request.ContentLength,
                          DateTime.UtcNow,
                          Stopwatch.StartNew());
                      return op;
  
                  }
  
              }
          }
      }
  </code></pre>
  
  <p>and this is my stack trace :</p>
  
  <blockquote>
    <p>at
    Microsoft.EntityFrameworkCore.Internal.ConcurrencyDetector.EnterCriticalSection()
    at
    Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.d__61.MoveNext()
    --- End of stack trace from previous location where exception was thrown --- at
    System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at
    System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
    task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at
    Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.d__59.MoveNext()
    --- End of stack trace from previous location where exception was thrown --- at
    System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at
    System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
    task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at
    Microsoft.EntityFrameworkCore.DbContext.d__48.MoveNext()
    --- End of stack trace from previous location where exception was thrown --- at
    System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at
    System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
    task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at
    Eela.Service.LogRepository.d__7.MoveNext() in
    D:\Eela\Eela.Service\LogRepository.cs:line 41 --- End of stack trace
    from previous location where exception was thrown --- at
    System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at
    System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
    task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at
    Eela.Web.Models.RequestLoggingMiddleware.d__5.MoveNext() in
    D:\Eela\Eela.Web\Models\RequestLoggingMiddleware.cs:line 82</p>
  </blockquote>
  
  <p><strong>Update :</strong></p>
  
  <p>I have a Middleware at my startup.cs :</p>
  
  <pre><code>app.UseMiddleware&lt;RequestLoggingMiddleware&gt;();
  </code></pre>
  
  <p>When I Comment it out, My code works without any problem.
  I include RequestLoggingMiddleware.cs source in my question.</p>
  
  <p>Where is the main problem ?  </p>