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

标签 database exception petapoco

在极少数情况下,我会遇到 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();
}

我使用依赖注入(inject)将其实例化为单例:

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

最佳答案

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

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

此外,还有一个内部计数器 (smarts),当它为零时将根据操作创建新连接或关闭现有连接。现在考虑到 PetaPoco 不是线程安全的,如果两个或多个线程同时递增/递减计数器等,这个内部计数器也可能会遇到与线程相关的问题。

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

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

快乐的 PetaPoco'ing

关于database - Peta poco - ExecuteReader 需要一个开放且可用的连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34631191/

相关文章:

sql - 如何将共享数据库从 Access 迁移到 SQL Express

c# - 无法更新所需的行

php - 将数据插入到不同的表中

java - 当我使用泛型方法时抛出类转换异常

c# - 如何使用 Petapoco 将自动增量 ID 设置为另一列

c# - 应用程序启动时在 Umbraco 中使用外键创建表的空引用

database - 如何创建我无权访问数据的 Web 应用程序?

java - 带有 Freemarker 的 Spring Framework 错误 Controller

java - 如何在 Forge 中获取 MinecraftServer 的实例?

sql - 使用 PetaPoco 执行参数化存储过程