首页 > 解决方案 > 在基本添加语句后保存更改调用超时的问题

问题描述

在我执行了一些基本的添加操作后,SaveChanges 调用超时,最后一次是将记录添加到桥接表。我不确定为什么会这样。谁能提供一些提示和建议?

我正在使用带有 EF Core 的 ASP.NET Core 作为 MSSQL Server 数据库的 ORM。

这是有问题的代码。

编辑:根据评论中的建议对代码进行了更改。

编辑 2:Appologies 我忘了提到我正在使用 .NET Core 2.2 和 EF Core 2.2.6

public AddToQueueResponse AddToQueue(AddToQueueRequest request)
{
    AddToQueueResponse response = new AddToQueueResponse();

    response = (AddToQueueResponse)request.CheckValidation(response);

    if (response.Status == HttpStatusCode.BadRequest)
        return response;

    var nickname = new Nicknames()
    {
        Sid = request.SID,
        NickName = request.Nickname
    };

    var item = new Queueitem()
    {
        Description = request.Description,
        TimeAdded = DateTime.Now,
        TopicId = request.TopicID
    };

    if (request.CheckInID.HasValue)
    {
        var checkIn = _checkInDataLayer.GetCheckIn(request.CheckInID.Value);

        if (checkIn == null)
        {
            response.Status = HttpStatusCode.NotFound;
            response.StatusMessages.Add(new StatusMessage(HttpStatusCode.NotFound, "Check in not in database."));
            return response;
        }
    }

    using (IDbContextTransaction trans = _queueDataLayer.GetTransaction())
    {
        try
        {
            if (!request.StudentID.HasValue)
            {
                _studentDataLayer.AddStudentNickname(nickname);
                _studentDataLayer.Save();

                if (nickname.StudentId == 0)
                {
                    throw new Exception("Unable to add student nickname");
                }
                request.StudentID = nickname.StudentId;
            }

            item.StudentId = request.StudentID.Value;

            _queueDataLayer.AddToQueue(item);
            _queueDataLayer.Save();

            if (request.CheckInID.HasValue)
            {
                Checkinqueueitem checkinqueueitem = new Checkinqueueitem()
                {
                    CheckInId = request.CheckInID.Value,
                    QueueItemId = item.ItemId
                };

                _checkInDataLayer.AddCheckinQueueItem(checkinqueueitem);
                _checkInDataLayer.Save();
            }

            response.ItemId = item.ItemId;
            response.Status = HttpStatusCode.OK;

            trans.Commit();
        }
        catch (Exception ex)
        {
            trans.Rollback();
            s_logger.Error(ex, "Unable to add queue item");
            response.Status = HttpStatusCode.InternalServerError;
            response.StatusMessages.Add(new StatusMessage(HttpStatusCode.InternalServerError, "Unable to add queue item"));
        }
    }
    return response;
}

标签: c#asp.net-core.net-coreentity-framework-coreasp.net-core-webapi

解决方案


我认为问题在于您有两层(队列和签入),我想它们有自己的 dbcontext,分别构建,因此具有不同的范围。从事务的第一个 dbcontext 锁定数据写入(在第二层中)。关键是您需要让两个上下文都使用相同的事务。是否对两个级别使用相同的上下文或在它们之间共享事务(https://docs.microsoft.com/en-us/ef/core/saving/transactions#cross-context-transaction-relational-databases-only)。也许您也可以尝试更改隔离级别,但这会更糟。


推荐阅读