Gratulujemy zdobycia SqlDependency
działa (wcale nie jestem sarkastyczny, wielu się w tym nie udało).
Nadszedł czas, aby przeczytać Tworzenie zapytania do powiadomienia temat na MSDN. Zobaczysz warunki, na jakich zapytania są ważne dla powiadomień, w tym ten wymóg:
Pisałem o podstawach SqlDependency
działa
, może wyjaśni kilka nieporozumień. Jako węzeł boczny, ponieważ używasz Linq, możesz być zainteresowany LinqToCache , który zapewnia pomost między Linq
zapytania i SqlDependency
.
Kolejny komentarz:nie używaj Start()
i Stop()
Twoja SqlDependency
nie chcąc. Wkrótce tego pożałujesz. Start()
ma być wywoływana dokładnie raz, podczas uruchamiania aplikacji, a Stop()
dokładnie raz podczas zamykania aplikacji (ściśle mówiąc, podczas ładowania i rozładowywania domeny aplikacji).
A teraz o twoim problemie:ważny jest poziom izolacji zapytania z powiadomieniem . Oznacza to, że zapytanie, do którego dołączasz subskrypcję, nie zapytanie, na którym wykonujesz UPDATE
(Nie będę komentował sensu robienia UPDATE pod brudnymi odczytami... lub mądrość używania brudnych odczytów do czegokolwiek
). O ile wiem, kod, który pokazujesz, nie powinien publikować zapytania pod read_uncommitted. Po wydaniu SET TRANSACTION ISOLATION ...
wszystkie kolejne transakcje (ergo wszystkie wyciągi) w tej sesji będą miały ten poziom izolacji. Zamykasz połączenie (poprzez usuwanie DataContext), a następnie używasz innego połączenia. Chyba że... korzystasz z pul połączeń. Witamy w klubie niewinnych ofiar :). Przecieki w puli połączeń powodują zmiany poziomu izolacji między Close()
/Open()
granice
. I to jest twój problem. Istnieje kilka prostych rozwiązań:
- Możesz (musisz!) zresetować poziom izolacji jawnie po
Open()
- Możesz użyć zakresów System.Transactions (moja rekomendacja). Obowiązkowa lektura: używanie nowej TransactionScope() uważane za szkodliwe
- Nie używaj puli połączeń.
A skoro już rozmawiamy, przeczytaj też to: Używanie tabel jako kolejek .