Félicitations pour avoir obtenu SqlDependency
travailler (je ne suis pas du tout sarcastique, beaucoup avaient échoué).
Il est maintenant temps de lire Creating a Query for Notification sujet sur MSDN. Vous verrez les conditions dans lesquelles les requêtes sont valides pour les notifications, y compris cette exigence :
J'ai écrit sur les bases de la façon dont SqlDependency
fonctionne
, peut-être dissipera-t-il certains malentendus. Et, en tant que nœud secondaire, puisque vous utilisez Linq, vous pourriez être intéressé par LinqToCache , qui fournit un pont entre Linq
requêtes et SqlDependency
.
Autre commentaire :ne pas Start()
et Stop()
votre SqlDependency
nilly-willy. Vous le regretterez bientôt. Start()
est censé être appelé exactement une fois, au démarrage de l'application, et Stop()
exactement une fois pendant l'arrêt de l'application (à proprement parler, c'est pendant le chargement et le déchargement du domaine d'application).
Maintenant, à propos de votre problème :le niveau d'isolement qui compte est celui de la requête notifiée . Cela signifie que la requête à laquelle vous attachez l'abonnement, pas la requête sur laquelle vous faites la UPDATE
(Je ne commenterai pas la sagesse de faire UPDATE sous des lectures sales... ou la sagesse d'utiliser des lectures sales pour tout
). Autant que je sache, le code que vous affichez ne doit pas publier la requête sous read_uncommitted. Après avoir émis un SET TRANSACTION ISOLATION ...
toutes les transactions suivantes (c'est-à-dire toutes les instructions) de cette session seront sous ce niveau d'isolement. Vous fermez la connexion (via la disposition du DataContext), puis utilisez une autre connexion. Sauf si ... vous utilisez des pools de connexion. Bienvenue dans le club des victimes innocentes :). Le regroupement des connexions fuit les changements de niveau d'isolement à travers Close()
/Open()
limites
. Et c'est votre problème. Il existe des solutions simples :
- Vous pouvez (devez !) réinitialiser explicitement le niveau d'isolement après
Open()
- Vous pouvez utiliser les champs d'application System.Transactions (ma recommandation). Lecture obligatoire : l'utilisation de new TransactionScope() est considérée comme nuisible
- N'utilisez pas le regroupement de connexions.
Et pendant que nous parlons, vous devez également lire ceci : Utilisation de tables comme files d'attente .