EntityFramework DbContext 生命周期 + Postgres:“操作已在进行中。”

2023-12-10

这几天我一直在搞乱以下内容。

我有一个在 Mono 上运行的 Nancy 应用程序,带有带有存储库模式和 UnitOfWork 的 EntityFramework 以及 Postgres。 Nancy 使用 TinyIoC 作为 IoC 容器。

我有一个网络应用程序,它在前端对请求进行排队,以便后端一次只处理一个请求。这一切都很好。

然而,当我运行一个连接到同一后端的 iOS 应用程序并且不会将请求排队到后端时,问题就开始了,有时几乎同时触发请求。

后端以随机间隔开始抛出此错误:

2016-09-20T13:30:16.120057436Z app[web.1]: System.Data.Entity.Core.EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details. ---> System.InvalidOperationException: An operation is already in progress.
2016-09-20T13:30:16.120104535Z app[web.1]:   at Npgsql.NpgsqlConnector.StartUserAction (ConnectorState newState) <0x41ad0150 + 0x00313> in <filename unknown>:0
2016-09-20T13:30:16.120113254Z app[web.1]:   at Npgsql.NpgsqlCommand.ExecuteDbDataReaderInternal (CommandBehavior behavior) <0x41acfe30 + 0x0002f> in <filename unknown>:0
2016-09-20T13:30:16.120119308Z app[web.1]:   at Npgsql.NpgsqlCommand.ExecuteDbDataReader (CommandBehavior behavior) <0x41acfe00 + 0x00013> in <filename unknown>:0
2016-09-20T13:30:16.120125313Z app[web.1]:   at System.Data.Common.DbCommand.ExecuteReader (CommandBehavior behavior) <0x41f1a3c0 + 0x00018> in <filename unknown>:0
2016-09-20T13:30:16.120131185Z app[web.1]:   at (wrapper remoting-invoke-with-check) System.Data.Common.DbCommand:ExecuteReader (System.Data.CommandBehavior)
2016-09-20T13:30:16.120206045Z app[web.1]:   at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<Reader>b__c (System.Data.Common.DbCommand t, System.Data.Entity.Infrastructure.Interception.DbCommandInterceptionContext`1 c) <0x41f1ac20 + 0x00027> in <filename unknown>:0
2016-09-20T13:30:16.120220450Z app[web.1]:   at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1[TInterceptor].Dispatch[TTarget,TInterceptionContext,TResult] (System.Data.Entity.Infrastructure.Interception.TTarget target, System.Func`3 operation, System.Data.Entity.Infrastructure.Interception.TInterceptionContext interceptionContext, System.Action`3 executing, System.Action`3 executed) <0x41b1d3c0 + 0x0010e> in <filename unknown>:0
2016-09-20T13:30:16.120232740Z app[web.1]:   at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader (System.Data.Common.DbCommand command, System.Data.Entity.Infrastructure.Interception.DbCommandInterceptionContext interceptionContext) <0x41f1a880 + 0x00263> in <filename unknown>:0
2016-09-20T13:30:16.120267802Z app[web.1]:   at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader (CommandBehavior behavior) <0x41f1a3f0 + 0x000e6> in <filename unknown>:0
2016-09-20T13:30:16.120274613Z app[web.1]:   at System.Data.Common.DbCommand.ExecuteReader (CommandBehavior behavior) <0x41f1a3c0 + 0x00018> in <filename unknown>:0
2016-09-20T13:30:16.120318116Z app[web.1]:   at (wrapper remoting-invoke-with-check) System.Data.Common.DbCommand:ExecuteReader (System.Data.CommandBehavior)
2016-09-20T13:30:16.120326788Z app[web.1]:   at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands (System.Data.Entity.Core.EntityClient.EntityCommand entityCommand, CommandBehavior behavior) <0x41f154c0 + 0x00043> in <filename unknown>:0
2016-09-20T13:30:16.120332587Z app[web.1]:   --- End of inner exception stack trace ---
2016-09-20T13:30:16.120336995Z app[web.1]:   at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands (System.Data.Entity.Core.EntityClient.EntityCommand entityCommand, CommandBehavior behavior) <0x41f154c0 + 0x000b3> in <filename unknown>:0
2016-09-20T13:30:16.120344218Z app[web.1]:   at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType] (System.Data.Entity.Core.Objects.ObjectContext context, System.Data.Entity.Core.Objects.ObjectParameterCollection parameterValues) <0x41f11e50 + 0x000a4> in <filename unknown>:0

我正在 Nancy 引导程序中注册依赖项:

protected override void ConfigureApplicationContainer (TinyIoCContainer container)
        {
            base.ConfigureApplicationContainer (container);

            Database.SetInitializer<ReflectDbContext> (new NullDatabaseInitializer<ReflectDbContext> ()); // add this to allow prevent "The context cannot be used while the model is being created"

        container.Register<IReflectDbContext, ReflectDbContext> ();
        container.Register<ReflectUnitOfWork> ().AsSingleton ();

        container.Register<IReflectUserRepository, ReflectUserRepository> ();
        container.Register<IUserRepository<ReflectUser>, ReflectUserRepository> ();

        container.Register<IReviewRepository, ReviewRepository> ();

        container.Register<IReviewSetupRepository, ReviewSetupRepository> ();

        container.Register<IRepositoryV2<ReflectUserActivityItem>, EntityFrameworkRepository<ReflectUserActivityItem>> ();

        container.Register<IAuthenticationUnitOfWork<ReflectUser, ReflectUserActivityItem>, ReflectUnitOfWork> ();

        container.Register<IRepository<ReflectUserActivityItem>, NullRepository<ReflectUserActivityItem>> (); //TODO remove this when port is complete

        container.Register<IErrorLogger, SimpleLogLogger> ();
        container.Register<IGeoIpDataProvider, TelizeGeoIpDataProvider> ();
        container.Register<IRepository<ReviewSetup>, ServiceStackOrmLiteRepository<ReviewSetup>> ();
        container.Register<IEmailExporter, MailChimpUserEmailDataExporter> ();
        container.Register<IMailer, SmtpMailer> ();
        container.Register<IUserManager<ReflectUser>, UserManager<ReflectUser, ReflectUserActivityItem>> ();
        container.Register<IUserMessageManager<ReflectUser>, UserMessageManager<ReflectUser>> ();

etc...

}

我有一种感觉,这是一个多线程问题,两个单独的请求使用相同的 DbContext (或底层连接),这会导致事情崩溃。

我已经尝试在中注册依赖项ConfigureRequestContainerNancy bootstrapper 的方法,但这会抛出“连接未打开”异常。

这个问题背后的理论在这篇文章中解释得很清楚:http://mehdi.me/ambient-dbcontext-in-ef6/

我不清楚以下内容:

  • 我假设这是一个多线程问题是否正确?
  • 我需要知道正确的方法来确保每个请求使用它自己的 DbContext/连接,这样东西就不会发生冲突,最好使用 TinyIoC/Nancy 来管理 DbContext 的生命周期。

我明白这是一个复杂的问题。如果您需要任何其他信息,请告诉我。

谢谢 :-)。


将稍微扩展我的评论,以供将来可能有相同错误的人参考。您可能已经知道,实体框架的DbContext遵循所谓的“工作单元”模式,这意味着您必须为一个逻辑工作片段(单元)使用一个实例。多个工作单元重复使用同一个实例是不希望的,在某些情况下,这样甚至可能导致失败。与 SQL Server 不同,Postgresql 不支持 MARS(多个活动结果集),这意味着它不支持同时通过同一连接执行多个命令。当您重用单个实例时DbContext从多个线程中,它们在执行命令时重复使用相同的底层 sql 连接,这会导致上述错误。

正如评论中所述,解决问题的方法始终是创建新的实例DbContext对于每个操作,然后进行处理。这意味着将其注册为

container.Register<IReflectDbContext, ReflectDbContext> ().AsMultiInstance();

并确保您永远不会存储DbConext静态字段中的实例 \ 另一个类的单例实例(例如您的ReflectUnitOfWork是单例,如果你存储DbContext在那里的一个领域-同样的问题再次出现)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

EntityFramework DbContext 生命周期 + Postgres:“操作已在进行中。” 的相关文章

  • 线程独占数据:如何存储和访问?

    NET 中是否有可能将对象实例绑定到线程的当前执行上下文 这样在代码的任何部分我都可以做类似的事情CurrentThread MyObjectData DoOperation 并确保我访问特定于线程的数据 谢谢 你可以看一下线程静态属性 h
  • C语言实现延时函数

    我想使用空循环实现延迟函数 但是完成一次循环所需的时间取决于编译器和机器 我希望我的程序自行确定时间并将程序延迟指定的时间 谁能给我任何想法如何做到这一点 注意 有一个名为delay 的函数可以将系统暂停指定的毫秒 是否可以在不使用此功能的
  • 如何用另一个静态变量初始化一个静态变量?

    静态1 hpp include
  • 更改图像颜色与透明背景

    我需要使用 c System Drawings 将透明背景上带有绿色圆圈的图像加载到位图图像中 这是最简单的部分 但是 我需要在将其添加到更大的图像之前更改圆圈的颜色 而不影响周围的透明度 就我而言 我需要将圆圈颜色更改为黄色并将其添加为太
  • C++:字符串流有什么好处?

    谁能告诉我一些在 C 中使用字符串流的实际例子 即使用流插入和流提取运算符输入和输出到字符串流 您可以使用字符串流来转换任何实现operator lt lt 到一个字符串 include
  • 等待运算符错误

    我的代码有问题 我怎么解决这个问题 这个问题出现在await操作符中 public MyModel HttpClient client new HttpClient HttpResponseMessage response await cl
  • 析构函数与成员函数竞赛

    当我在析构函数内时 其他线程是否可能开始执行对象的成员函数 遇到这种情况该如何处理呢 C 没有内在的保护来防止在删除对象后使用它 忘记竞争条件 另一个线程可以在完全删除你的对象后使用你的对象 Either 确保只有一个位置 代码拥有该对象
  • 更改实体的可访问性

    我想建立一个内部实体 我已将实体 其标量属性和导航属性更改为内部 当我尝试构建它时出现此错误 错误 6036 EntityType 文件 具有 内部 可访问性 EntitySet 文件 具有具有 公共 可访问性的 get 属性 Entity
  • 将视频上传/保存到数据库或文件系统

    我以前从未尝试过保存视频 所以我对此了解不多 我知道如果视频很小 我可以转换为字节数组并保存到数据库 但是为了提高效率 我想了解如何将任何上传的视频保存到我的服务器文件中 然后只保存该文件的文件路径我的数据库表中的视频 我完全不知道如何开始
  • 我如何知道向量的实际最大大小? (不使用 std::vector::max_size)

    在在线课程中 我正在学习向量 在其中一个例子中 他们解释说 std vector max size 应该给我向量可以达到的最大大小 我决定测试一下 include
  • 可以通过模板间接访问基类中的私有类型

    我试图在编译时根据类型是否在给定范围内公开可用来选择要使用的类型 最好直接看代码 include
  • 使用信号和槽更新指针

    我对 Qt 很陌生 请帮我解决这个问题 我正在使用线程在后台执行密集操作 同时我想更新 UI 所以我使用 SIGNALS 和 SLOTS 为了更新 UI 我发出一个信号并更新 UI 让我们考虑下面的示例代码 struct sample QS
  • 将旧的 Unity 代码升级到 Unity 5

    在触发按钮上播放动画的代码似乎不起作用 我在 Youtube 上看到了一个视频 内容很简单animation Play 它可以在该视频上运行 但我无法让它在我的计算机上运行 我做错了什么还是团结改变了它 请帮助我在网上找不到解决方案 所有
  • Rx 在不同的线程上生产和消费

    我试图通过此处的示例代码来简化我的问题 我有一个生产者线程不断地输入数据 并且我尝试在批次之间添加时间延迟来对其进行批处理 以便 UI 有时间渲染它 但结果并不如预期 生产者和消费者似乎在同一个线程上 我不希望批处理缓冲区在正在生成的线程上
  • 如何在realm-dotnet中存储System.Collections.Generic.Dictionary

    我正在尝试将 Realm NET 集成到我的 uwp 项目中 我想知道是否有任何方法可以在 Realm dotnet 库中存储 System Collections Generic Dictionary 我试过这个 public class
  • NSubstitute - 测试特定的 linq 表达式

    我在当前正在开发的 MVC 3 应用程序中使用存储库模式 我的存储库界面如下所示 public interface IRepository
  • 使用 DataGridViewCheckboxCell 真正禁用 DataGridView 中的复选框

    有谁知道如何使用 DataGridViewCheckboxCell 禁用 DataGridView 中的复选框 我可以将其设置为只读 并设置背景颜色 但我无法让复选框本身显示为禁用状态 有什么想法吗 Guess 你必须自己画 http so
  • 如何使用 .NET 捕获我的桌面视频?

    我想知道是否有任何方法可以使用 NET 捕获我的桌面的视频 截屏视频 我并不是在寻找截屏软件 而只是在寻找一种可以让我自己生成桌面视频的技术 我想过拍摄多个屏幕截图 但我不确定如何以编程方式生成带有图像序列的视频 有人有主意吗 Thanks
  • 从其对象获取结构体字段的名称和类型

    例如 我有一个类似这样的结构 struct Test int i float f char ch 10 我有一个该结构的对象 例如 Test obj 现在 我想以编程方式获取字段名称和类型obj 是否可以 顺便说一句 这是 C 你正在要求C
  • 为什么 INT64_MIN 的定义不同?为什么他们的行为不同?

    The stdint h我公司的标题是 define INT64 MIN 9223372036854775808LL 但在我项目的一些代码中 一位程序员写道 undef INT64 MIN define INT64 MIN 92233720

随机推荐