question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

a question about DbContext's Lifetime

See original GitHub issue

when API access more some access has error An unhandled exception was thrown by the application. System.InvalidOperationException: A second operation was started on this context before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913. some access is success

when I restart service it’s will be ok;

webapi:

        [HttpPut("{id}")]
        [DisplayName("PutProduct")]
        public async Task<Response<bool>> PutProduct(long id, [FromBody] UpdateChProductModel data)
        {
            var temp = await _context.ChProducts.FirstOrDefaultAsync(x => x.Id == id);
            if (temp == null)
                return ResultBuilder.FailResult(false, "product is not exist");

            temp.Status = data.Status;
            temp.PurPrice = data.PurPrice;
            temp.LastUpdate = DateTime.Now;

            await _context.SaveChangesAsync();

            await _operateLogSvr.SaveLog(_curUserHelp.UserInfo.Id, LogType.ChProd,
                _curUserHelp.UserInfo.Name + "PutProduct:" + JsonSerializer.Serialize(temp));

            return ResultBuilder.SuccessResult(true, "success");
        }

injection:

        private readonly QYSDbContext_context;
        private readonly IOperateLogService _operateLogSvr;
        private readonly CurUserHelp _curUserHelp;

        /// <summary>
        /// Product
        /// </summary>
        /// <param name="context"></param>
        /// <param name="operateLogSvr"></param>
        /// <param name="curUserHelp"></param>
        public ProductController(QYSDbContext context, IOperateLogService operateLogSvr, CurUserHelp curUserHelp)
        {
            _context = context;
            _operateLogSvr = operateLogSvr;
            _curUserHelp = curUserHelp;
        }

IOperateLogService’s info:

    public class OperateLogService : IOperateLogService
    {

        private readonly IServiceScopeFactory _serviceScopeFactory;
        private readonly CommLogNo _commLogNo;

        public OperateLogService(IServiceScopeFactory serviceScopeFactory, CommLogNo commLogNo)
        {
            _serviceScopeFactory = serviceScopeFactory;
            _commLogNo = commLogNo;

        }

        /// <summary>
        /// add
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="type"></param>
        /// <param name="remark"></param>
        /// <returns></returns>
        public async Task SaveLog(long userId, LogType type, string remark)
        {
            var operateLog = new OperateLog
            {
                Id = _commLogNo.NewId(),
                Type = type,
                UserId = userId,
                Remark = remark,
                CreateTime = DateTime.Now,
            };

            using var scope = _serviceScopeFactory.CreateScope();
            var context = scope.ServiceProvider.GetRequiredService<QYSDbContext>();
            await context.OperateLogs.AddAsync(operateLog);
            await context.SaveChangesAsync();
        }
     }

AddDbContext:

                services.AddDbContextPool<QYSDbContext>((p, options) =>
                {
                    var svr = p.GetService<SaveChangeTrigger>();
                    options.AddInterceptors(svr);

                    options.UseMySql(_configuration.GetValue<string>("ConnectionStrings:cgmysql"),
                        ServerVersion.AutoDetect(_configuration.GetValue<string>("ConnectionStrings:cgmysql")));
                });

why this error is happened in OperateLogService, I use IServiceScopeFactory

how can I fixed it

change AddDbContextPool to AddDbContext and set ServiceLifetime to ServiceLifetime.Transient or set scope.ServiceProvider.GetRequiredService to scope.ServiceProvider.GetService ?

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
rojicommented, Sep 7, 2022

Closing for now, can reopen if the details are provided.

0reactions
QianYScommented, Sep 9, 2022
2022-09-01 15:10:57.318 +08:00 [ERR] Connection id "0HMK9FQDN9BSE", Request id "0HMK9FQDN9BSE:00000002": An unhandled exception was thrown by the application.
System.InvalidOperationException: A second operation was started on this context before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.
   at Microsoft.EntityFrameworkCore.Internal.ConcurrencyDetector.EnterCriticalSection()
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IList`1 entriesToSave, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(DbContext _, Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
   at Pomelo.EntityFrameworkCore.MySql.Storage.Internal.MySqlExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
   at ZR.Charge.Service.Services.OperateLogService.SaveLog(Int64 userId, LogType type, String remark) in /var/lib/jenkins/workspace/CG_Mng/ZrCharge/ZR.Charge.Service/Services/OperateLogService.cs:line 45
   at ZR.Charge.Mng.Api.Controllers.Mng.ChProductController.Put(Int64 id, UpdateChProductModel data) in /var/lib/jenkins/workspace/CG_Mng/ZrCharge/ZR.Charge.Mng.Api/Controllers/Mng/ChProductController.cs:line 176
   at lambda_method2644(Closure , Object )
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
Read more comments on GitHub >

github_iconTop Results From Across the Web

How should I manage DbContext Lifetime in MVC Core?
Entity Framework contexts should be added to the services container using the Scoped lifetime. This is taken care of automatically if you use ......
Read more >
DbContext lifetime in desktop app with SQLite
DbContext isn't designed for application state - it's an implementation of the Unit Of Work pattern for CRUD operations to/from your database ( ......
Read more >
When Your DbContext Has The Wrong Scope - Haacked
So to summarize, DbContext still has a lifetime of Scoped while DbContextFactory and DbContextOptions have a Singleton lifetime. And EF Core is ...
Read more >
Best Practices in Using the DbContext in EF Core
DbContext controls its lifespan; after your data access request is complete, DbContext will automatically close the database connection for ...
Read more >
Managing DbContext in EFCore6 (the right way) : r/dotnet
Question 1: Will it be the same DbContext object in both repositories? ... it will be registered in DI container using Scoped lifetime....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found