/ / Peta poco - ExecuteReader wymaga otwartej i dostępnej bazy danych połączeń, wyjątku, petapoco

Peta poco - ExecuteReader wymaga otwartej i dostępnej bazy danych połączeń, wyjątku, petapoco

W rzadkich sytuacjach mam pewne problemy z petapokiem.

Czasami otrzymuję następujący wyjątek:

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()

Naprawdę nie wiem co z tym zrobić. Czy ktoś to widział wcześniej? Wszelkie sugestie, dlaczego tak się dzieje i co z tym zrobić?

Nie mogę go odtworzyć, ponieważ zdarza się to rzadko (może być to 2-3% wywołań db)

Używam wersji 5.0.1 petapoco.

Dzięki! :)

EDYTOWAĆ:

Korzystam z następującego konstruktora do utworzenia instancji bazy danych:

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

Tworzę go jako singleton używając iniekcji zależności jak poniżej:

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

Odpowiedzi:

1 dla odpowiedzi № 1

Kiedy po raz pierwszy przeczytałem post, pomyślałem ah awątek błędu. Nie chciałem jednak po prostu pisać, bez żadnego wyjaśnienia: FYI, jakikolwiek błąd, który jest niespójny w tej aplikacji internetowej, jest najprawdopodobniej błędem.

Ok, więc dlaczego jest to błąd w wątku. Używasz PetaPoco jako pojedynczej instancji, co oznacza jedną instancję dla całej aplikacji, działa głównie dlatego, że PetaPoco ma wewnętrzne smartsy, aby wiedzieć, kiedy otwierać / zamykać wspólne połączenie, i tylko przez samo szczęście, użycie PetaPoco Nie kolidują, z wyjątkiem 2-3% przypadków.

Ponadto istnieje wewnętrzny licznik(smarts), który, gdy zero spowoduje albo utworzenie nowego połączenia, albo zamknięcie istniejącego, w zależności od operacji. Biorąc pod uwagę, że PetaPoco nie jest bezpieczny dla wątków, ten wewnętrzny licznik może również cierpieć z powodu problemu związanego z gwintowaniem, jeżeli dwa lub więcej wątków zwiększa lub zmniejsza licznik w tym samym czasie itd.

TDLR; W dotnet obowiązuje ogólna zasada: zakładać / tworzyćmetody statyczne są bezpieczne dla wątków, a wszystko inne nie jest bezpieczne dla wątków, z wyjątkiem sytuacji wyraźnie zaznaczonych i tam, gdzie ma to sens. Używanie PetaPoco działałoby, gdyby PetaPoco było wątkowo bezpieczne, ale tak nie jest. Aby rozwiązać ten problem, utwórz nowe wystąpienie programu PetaPoco dla każdego żądania; dość tania operacja (bardziej płynna konfiguracja).

Widzę, że używasz PetaPoco 5.0.1, sugeruję przejrzenie najnowszego wydania, ponieważ jest to nowa funkcja FluentConfiguration, a tak się składa, że ​​strona dokumentacji tej funkcji u dołu strony ma konfigurację przykładowego kontenera. Proponuję sprawdzić to. . Dokumentacja

Happy PetaPoco "er" ing