Peta poco - ExecuteReader 需要一个开放且可用的连接

Peta poco - ExecuteReader requires an open and available Connection

在极少数情况下,我会遇到一些 petapoco 问题。

有时我会遇到以下异常:

System.InvalidOperationException: ExecuteReader requires an open and available Connection. The connection's current state is connecting.
   at System.Data.SqlClient.SqlConnection.GetOpenConnection(String method)
   at System.Data.SqlClient.SqlConnection.ValidateConnectionForExecute(String method, SqlCommand command)
   at System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader()
   at PetaPoco.Database.<Query>d__44`1.MoveNext()

我真的不知道该怎么办。谁看过这个吗?关于为什么会发生以及如何处理有什么建议吗?

我无法重现它,因为它很少发生(可能占数据库调用的 2-3%)

我使用的是 petapoco 5.0.1 版。

谢谢! :)

编辑:

我正在使用以下构造函数来实例化数据库:

public Database(string connectionString, string providerName)
{
    _connectionString = connectionString;
    _providerName = providerName;
    CommonConstruct();
}

我正在使用依赖注入将其实例化为单例,如下所示:

Container.Register(Component.For<IDatabase>().ImplementedBy<Database>().UsingFactoryMethod(() => new Database(configuration.ConnectionString, configuration.DbFactoryProvider)).LifestyleSingleton());

当我第一次阅读 post 时,我以为啊一个线程错误。然而,我并不想不加解释地就这样把它注销。仅供参考,网络应用程序中任何像这样不一致的错误很可能是线程错误。

好的,那为什么是线程错误。您将 PetaPoco 用作单例实例,这意味着整个应用程序只有一个实例。它之所以有效,主要是因为 PetaPoco 具有内部智能,可以知道何时 open/close 共享连接,而且幸运的是,PetaPoco 的用法不会发生冲突,除了 2-3% 的时间。

此外,还有一个内部计数器 (smarts),当它为零时,将根据操作创建新连接或关闭现有连接。现在考虑到 PetaPoco 不是 thread-safe,如果两个或更多线程同时 increment/de-increment 计数器等

,这个内部计数器也可能会遇到与线程相关的问题

TDLR; 在 dotnet 中,一般规则是 assume/make 静态方法 thread-safe 和其他所有不是 thread-safe,除非明确标记以及有意义的地方。如果 PetaPoco 为 thread-safe,您对 PetaPoco 的使用将有效,但事实并非如此。要解决此问题,请为每个请求创建一个新的 PetaPoco 实例;相当便宜的操作(流畅的配置更是如此)。

我看到您使用的是 PetaPoco 5.0.1,我建议查看最新版本,因为它有一个新的 FluentConfiguration 功能。碰巧的是,此功能的文档页面在页面底部有一个示例容器设置。我建议你检查一下。 Documentation

PetaPoco'ing 快乐