2011-09-11 1 views
3

J'ai un service WCF qui provoque parfois un blocage de la base de données. Mon service vous permet de soumettre des demandes au conseil, il vous permet également de les charger à nouveau car le conseil peut les mettre à jour. Chacune des applications a un certain nombre de documents associés.Comment puis-je éviter les interblocages avec des requêtes lentes

Donc, si un ensemble d'événements comme celui-ci se produisent sur mon service

1) Application #1 is submitted 
2) A document is uploaded for application #1 
3) Application #1 is loaded 
4) Part 2 above finishes 

Deadlock à partie 3. Je crois que la raison est que le document dans la partie 2 prend un certain temps pour soumettre au serveur SQL de la Service WCF, et pendant ce temps, il verrouille la table. Par conséquent, si nous chargeons à partir de l'application de base de données n ° 1, nous rencontrons des problèmes avec les documents associés. J'utilise le framework d'entité. Comment puis-je resoudre ceci? Tout ce que je veux vraiment faire est de charger les documents dans cette circonstance qui sont complètement soumis et ne pas courir dans la table étant verrouillé ou quoi que ce soit.

Par la façon dont c'est l'erreur spécifique que je reçois,

Message: Transaction (Process ID 93) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction. 

MISE À JOUR: J'ai eu quelques commentaires que je pouvais changer l'ordre des opérations. Je ne peux pas le faire parce que les parties 2 et 3 proviennent d'appels différents au service WCF. Il appartient donc à l'utilisateur du service de commander les opérations. «Demandez-leur de le changer», dites-vous, mais ce n'est pas si simple non plus. L'ordre des opérations dépend en réalité de l'utilisateur final qui vient 'actualiser' son navigateur au bon moment.

Mise à jour # 2: J'ai besoin de quelques conseils sur la façon de répliquer ce problème. J'ai écrit une application de test et la partie 2 ci-dessus bloque l'opération dans la partie 3, mais les conséquences pour moi est que l'opération 3 bloque jusqu'à ce que l'opération 2 soit terminée, et l'opération 3 se termine. Donc cela signifie que la partie 3 prend 1 minute 50 secondes au lieu de 3 normalement. Des idées pour lesquelles ça bloquerait pour moi et ne créerait pas une impasse? Cela peut-il être lié à la quantité totale de trafic de base de données sur ce serveur vu que j'utilise un serveur de test, ou est-ce que certains paramètres de base de données pourraient l'affecter?

Répondre

1

Il y a plusieurs façons d'éviter des impasses en général (SQL Server et d'autres bases de données):

1) Appel saveChanges() seulement à la fin de la transaction, pour exécuter toutes les requêtes ensemble.

2) Modifiez l'ordre d'exécution de la mise à jour de la base de données, effectuez d'abord toutes les lectures (SELECT) et effectuez toutes les mises à jour en dernier.

3) Effectuer les lectures hors de la transaction des données qui ne seraient pas modifiées dans la transaction. 4) Changer le niveau d'isolement de la transaction en SERIALIZABLE (mauvaise performance) ou SNAPSHOT ou autre intermédiaire sans verrouillage comme READ UNCOMMITTED si la logique de l'application le permet.

5) Créer des blocs de code synchronisés en utilisant lock(lock_object) pour éviter que deux threads effectuent la même transaction en parallèle ou effectuent deux transactions différentes qui se verrouillent eux-mêmes.

+0

J'ai mis à jour la question. Je ne peux pas vraiment contrôler l'ordre des opérations. Ma solution devrait se rapporter à la partie 4 ou 5 de votre réponse. La partie 5 commence à paraître plus improbable, car il pourrait y avoir un certain nombre de threads en même temps. – peter

+0

Vous pouvez avoir plusieurs threads en cours d'exécution, mais vous avez seulement besoin de synchroniser les parties du code effectuant les opérations qui mènent à un dead-lock. Cela réduit le débit global mais l'autre option consiste à modifier le niveau d'isolation pour éviter les verrouillages. Niveau d'isolement SNAPSHOT, nouveau dans SQL Server 2005 tente de résoudre le problème avec dead-lock; au lieu de créer des verrous lors du changement de données, stocke différentes versions de données et chaque transaction lit la version des données dont elle a besoin. –

+0

J'ai coché votre réponse parce que c'était la première fois. Je pense que le problème peut être atténué un peu. La requête qui a provoqué l'impasse tirait un champ hors de la base de données (un blob) dont il n'avait pas besoin. Cela signifie qu'en supprimant ce champ de la requête, la requête sera plus rapide et donc moins susceptible de se produire lorsque la table est verrouillée. Comprendre le vrai problème va être plus difficile parce que ce que je suis sûr que cela pourrait causer un blocage, mais il devient un peu plus compliqué de déterminer ce qui cause réellement une impasse. – peter

1

Quelques solutions:

  • Utilisez un niveau d'isolement de la lecture non validée si vous ne me dérange pas d'avoir potentiellement des lignes non validées apparaissent à l'étape 3 (cela dépend de votre situation).

OU

  • lot vos modifications sur votre contexte EF plus efficace et assurez-vous qu'ils exécutent à la fois (sans voir votre code Je ne suis pas sûr que vous faites cela ou non)

EDIT

Le lien ci-dessous peut également être utile dans le dépannage et résoudre votre problème:

http://blogs.msdn.com/b/bartd/archive/2006/09/09/deadlock-troubleshooting_2c00_-part-1.aspx

+0

Je ne peux pas contrôler l'ordre des opérations. J'ai mis à jour ma question. Ma solution devrait se rapporter au niveau d'isolement je pense. – peter

Questions connexes