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