我正在从 netcoreapp 2.1 迁移到 3.1,并且发现了 EF core 3.1 的重大更改,但我无法解决。以下内容在 2.1 中有效,因此简单地说数据库上下文在设计上不是线程安全的,并指出其他不涉及此细微差别的问题并不能解决当前的问题。
之前在 2.1 中,这是有效的:
taskList.Add(MethodOne(myRequestObject));
taskList.Add(MethodTwo(myRequestObject));
await Task.WhenAll(taskList);
这两种方法都只从数据库上下文中读取(从未更改),看起来像这样:
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 中,即使我只是读取而不更改实体,数据库上下文 ConcurrencyDetector 也认为它已经EnterCriticalSection
当第二个方法尝试在 DbContext 上等待时,这会导致异常:
InvalidOperationException:在此上下文上启动了第二个操作
在上一个操作完成之前
为了基线理智,我还尝试了以下方法,它确实有效(但对于我的应用程序的实际代码来说不是理想的解决方案):
await MethodOne(myRequestObject);
await MethodTwo(myRequestObject);
这是我的问题:
- 当我知道安全时,有没有办法继续告诉 EF core 3.1 允许并发。这在 2.1 中有效,所以很明显,不能通过简单地说数据库上下文在设计上从未允许这样做并将问题作为重复项来关闭来忽略这一点。我的应用程序已经在生产中愉快地运行了很长一段时间。只有在迁移到 3.1 后,这才成为问题。发生了什么变化?这种改变真的不可能解决吗?还是有例外情况,即上下文不允许这样做?如果这在“设计不允许”之前有效,那么现在是否也同样不成立?
当我知道安全时,有没有办法继续告诉 EF core 3.1 允许并发。这在 2.1 中有效,所以很明显,不能通过简单地说数据库上下文在设计上从未允许这样做并将问题作为重复项来关闭来忽略这一点。
数据库上下文从来不允许这样做。我从未见过这种代码可以在任何版本的 .NET Core 上运行。如果它happened在 2.x 中工作,它只是“工作”,因为代码赢得了其竞争条件,因此只是运气好。任何性能变化(内存减少、防病毒软件、备用网络路由)都可能导致此失败。认识到代码是错误的非常重要并且一直都是.
我的应用程序已经在生产中愉快地运行了很长一段时间。只有在迁移到 3.1 后,这才成为问题。发生了什么变化?
可能是框架中的一些时间。
如果这在“设计不允许”之前有效,那么现在是否也同样不成立?
竞争条件仍然存在。如果您的代码碰巧赢得了竞争条件,您将不会看到该异常。
这种改变真的不可能解决吗?还是有例外情况,即上下文不允许这样做?
没有解决方法可以强制 dbcontext 处理多个并发请求。执行并发请求的正常模式是使用多个 dbcontext,每个并发请求一个。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)