Quantcast
Channel: ASP.NET Core
Viewing all articles
Browse latest Browse all 9386

Entity Framework Core: The transaction operation cannot be performed because there are pending requests working on this transaction.

$
0
0

In the process of creating a Web API. While testing I've ran into some problem when loging requests to the database. The problem happens when I spam the API with many requests.

I will try to include as much code as possible for what could be relevant.

I started out having all my services as scoped and then I ran into the following exception: 'A second operation started on this context before a previous operation completed. Any instance members are not guaranteed to be thread safe.'

My first thought was that loggingService needed to be transient but after changing that I instead ran into the exception in the title of this post. So I changed all the services that are involved with the request/response database logging to Transient, but that didn't help.

The exception occurs when doing SaveChanges trying to update the database record in the ResponseDatabaseLogger (same post as written to with the RequestDatabaseLogger).

Startup:

services.AddTransient<ILoggingService, LoggingService>();
services.AddTransient<IResponseDatabaseLogger, ResponseDatabaseLogger>();
services.AddTransient<IRequestDatabaseLogger, RequestDatabaseLogger>();

services.AddTransient<ActionFilter>();

ActionFilter.cs:

namespace ...
{
    public class ActionFilter : ActionFilterAttribute
    {
        private readonly IResponseDatabaseLogger _responseDatabaseLogger;
        private readonly IRequestDatabaseLogger _requestDatabaseLogger;
        public ActionFilter(IResponseDatabaseLogger responseDatabaseLogger, IRequestDatabaseLogger requestDatabaseLogger)
        {
            _responseDatabaseLogger = responseDatabaseLogger;
            _requestDatabaseLogger = requestDatabaseLogger;
        }

        public override void OnActionExecuting(ActionExecutingContext context)
        {
            long logId = _requestDatabaseLogger.Log(context);
            context.HttpContext.AddCurrentLogId(logId);

            base.OnActionExecuting(context);
        }

        public override void OnActionExecuted(ActionExecutedContext context)
        {
            _responseDatabaseLogger.UpdateCurrentLog(context);

            base.OnActionExecuted(context);
        }

        public override void OnResultExecuting(ResultExecutingContext context)
        {
            base.OnResultExecuting(context);
        }

        public override void OnResultExecuted(ResultExecutedContext context)
        {
            base.OnResultExecuted(context);
        }
    }
}

RequestDatabaseLogger.cs:

namespace ...
{

    public class RequestDatabaseLogger : IRequestDatabaseLogger
    {
        private readonly ILoggingService _loggingService;
public RequestDatabaseLogger(ILoggingService loggingService) { _loggingService = loggingService; } public long Log(ActionExecutingContext context) { long? systemUserId = context.HttpContext.GetSystemUserId(); string url = context.HttpContext.Request.GetFullRequestPath(); string action = GetAction(context); string actionArguments = GetActionArguments(context); string clientIPAddress = context.HttpContext.GetClientIPAddress(); var logEntry = _loggingService.AddApiLog(context.HttpContext.TraceIdentifier, systemUserId, url, action, DateTime.UtcNow, actionArguments, clientIPAddress); _loggingService.SaveChanges(); return logEntry.Id; } } }

ResponseDatabaseLogger.cs:

namespace ...
{
    public class ResponseDatabaseLogger : IResponseDatabaseLogger
    {
        private readonly ILoggingService _loggingService;

        public ResponseDatabaseLogger(ILoggingService loggingService)
        {
            _loggingService = loggingService;
        }

        public void UpdateCurrentLog(ActionExecutedContext context)
        {
            long? systemUserId = context.HttpContext.GetSystemUserId();
            ApiLogStatus apiLogStatus = GetResponseStatus(context);

            _loggingService.UpdateApiLog(context.HttpContext.GetCurrentLogId(), systemUserId ?? -1, apiLogStatus, DateTime.UtcNow);
            _loggingService.SaveChanges();
        }
    }
}

Hopefully someone can point me in the right direction here.


Viewing all articles
Browse latest Browse all 9386

Trending Articles