“在此上下文中启动第二个操作"EF 核心 3.1 并发中断更改 [英] “A second operation started on this context” EF core 3.1 concurrency breaking change

查看:27
本文介绍了“在此上下文中启动第二个操作"EF 核心 3.1 并发中断更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在从 netcoreapp 2.1 迁移到 3.1,我发现 EF 核心 3.1 有一个我无法解决的重大更改.以下内容在 2.1 中有效,所以简单地说 db 上下文在设计上不是线程安全的,并指出其他不涉及这种细微差别的问题并不能解决手头的问题.

I'm migrating from netcoreapp 2.1 to 3.1, and I've found a breaking change for EF core 3.1 that I can't resolve. The following worked in 2.1 so simply saying db context isn't thread safe by design and pointing to other questions that don't deal with this nuance does not address the issue at hand.

以前在 2.1 中,这有效:

Previously in 2.1, this worked:

taskList.Add(MethodOne(myRequestObject));
taskList.Add(MethodTwo(myRequestObject));

await Task.WhenAll(taskList);

这两种方法都只从数据库上下文中读取(从不改变),看起来像这样:

where both methods only read(never changed) from the db context and look something like this:

private async Task MethodOne(RequestObject myRequestObject)
{
    var entity = await DbContext
    .MyDbSet
    .OrderByDescending(x => x.SomeProperty)
    .FirstOrDefaultAsync(x => x.Id == myRequestObject.Id);

    if (entity != null)
        myRequestObject.SomeRequestProperty = entity.AnotherProperty;
    }
}

在 3.1 中,即使我只是在读取而不是更改实体,DB 上下文 ConcurrencyDetector 也认为它具有 EnterCriticalSection,当第二种方法尝试在 DbContext 上等待时会导致异常:

In 3.1, even when I'm just reading and not changing the entities, the DB context ConcurrencyDetector thinks it has EnterCriticalSection which causes an exception when the second method tries to await on the DbContext:

InvalidOperationException:在此上下文中启动了第二个操作在上一个操作完成之前

InvalidOperationException: A second operation started on this context before a previous operation completed

对于基线健全性,我还尝试了以下可行的方法(但对于我的应用程序的真实代码来说不是理想的解决方案):

For baseline sanity, I also tried the following which does work(but is not an ideal solution for the real code of my app):

await MethodOne(myRequestObject);
await MethodTwo(myRequestObject);

这是我的问题:

  1. 当我知道它是安全的时,有没有办法继续告诉 EF 核心 3.1 允许并发.这在 2.1 中有效,所以很明显,这不能通过简单地说 db context 设计从未允许这样做并将问题关闭为重复项而被驳回.我的应用程序已经在生产环境中愉快地运行了很长时间.只有在迁移到 3.1 之后,这才成为一个问题.发生了什么变化?这种变化是否真的无法解决,或者上下文不允许这样做的说法是否有例外?如果这在设计不允许"之前有效,那么现在是否也可能同样不正确?

推荐答案

当我知道它是安全的时,有没有办法继续告诉 EF 核心 3.1 允许并发.这在 2.1 中有效,因此显然不能通过简单地说 db context 设计从未允许这样做并将问题关闭为重复来驳回这一点.

Is there a way to continue to tell EF core 3.1 to allow concurrency when I know it is safe. this worked in 2.1 so clearly this cannot be dismissed by simply saying db context has never allowed this by design and closing the question as a duplicate.

数据库上下文从未允许这样做.我从未见过这种代码适用于任何版本的 .NET Core.如果它碰巧在 2.x 中工作,那么它只是工作",因为代码赢得了竞争条件,因此只是走运.任何性能变化——内存减少、防病毒软件、备用网络路由——都可能导致此失败.认识到代码是错误的并且一直是是非常重要的.

The DB context has never allowed that. I've never seen this kind of code work on any version of .NET Core. If it happened to work in 2.x, it was only "working" in the sense that the code was winning its race conditions and thus just getting lucky. Any change in performance - reduced memory, antivirus software, alternate network routing - could have caused this to fail. It's very important to recognize that the code is wrong and always has been.

我的应用已经在生产环境中愉快地运行了很长时间.只有在迁移到 3.1 之后,这才成为一个问题.发生了什么变化?

My app has been running happily in production for a long time. Only after migrating to 3.1 has this become an issue. What has changed?

可能是框架中的一些时间.

Probably some timing in the framework.

如果这在设计不允许"之前有效,那么现在是否也可能同样不正确?

If this worked before when this 'wasn't allowed by design', is it possible that it is similarly not true now as well?

竞争条件仍然存在.如果您的代码碰巧赢得了竞争条件,您将不会看到该异常.

The race condition still exists. If your code happens to win the race condition, you won't see that exception.

是否真的无法解决此更改,或者是否存在上下文不允许的声明的例外情况?

Is this change truly impossible to work around or are there exceptions to the claim that the context doesn't allow this?

没有强制 dbcontext 处理多个同时请求的解决方法.执行并发请求的正常模式是使用多个 dbcontexts,每个并发请求一个.

There's no workaround to force a dbcontext to work with multiple simultaneous requests. The normal pattern for doing simultaneous requests is to use multiple dbcontexts, one for each simultaneous request.

这篇关于“在此上下文中启动第二个操作"EF 核心 3.1 并发中断更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆