2010-09-20 4 views
0

J'ai une application .net qui doit exécuter une série d'étapes dans un travail. Chaque étape vit dans sa propre transaction et toutes les tâches sont exécutées en série (pas d'async explicite). Les deux dernières tâches sont une transformation de données et une récupération de données des données transformées. Nous obtenons des erreurs d'interblocage à partir de ces deux dernières étapes, car la dernière étape ressemble à essayer d'obtenir des données que l'étape précédente a encore verrouillé.Les procédures stockées programmées pour déclencher des transactions série distinctes semblent s'exécuter simultanément

Est-il possible que SQL signale que l'exécution est terminée, avant qu'il ne l'est réellement? Un verrou peut-il persister dans une transaction terminée? Y a-t-il autre chose que je devrais rechercher pour comprendre ce qui se passe?

Par série, je veux dire l'un après l'autre. Chaque transaction est terminée avant que la suivante ne commence. Si des échecs se produisent, cette transaction est annulée et l'ensemble du processus arrêté pour permettre à l'utilisateur de réessayer.

Répondre

0

Etes-vous sûr qu'un COMMIT ou ROLLBACK est émis avant les dernières étapes? Le serveur SQL signalera l'achèvement de tout lot de requêtes - mais la fin d'un batch de requêtes ne signifie pas nécessairement que la transaction est terminée, à moins que ce lot n'émette un COMMIT ou ROLLBACK.

Locks doivent tous être libérés à la fin d'une transaction, mais il faut savoir que les transactions peuvent être imbriquées (http://msdn.microsoft.com/en-us/library/ms189336%28v=SQL.90%29.aspx)

En outre, il se peut que vos blocages sont du même processus exécutant simultanément - c'est même Bien que votre processus ne puisse pas se bloquer lorsqu'il est exécuté seul, s'il s'exécute simultanément (par exemple avec plusieurs utilisateurs), vous pouvez toujours obtenir un interblocage, ou si vous avez d'autres processus qui acquièrent également les mêmes verrous. Une façon de le faire peut être atténuée en acquérant toujours vos serrures dans le même ordre, mais il existe de nombreuses autres stratégies qui peuvent être utilisées selon votre situation.

Modifier: vous pouvez également consulter ce lien: http://msdn.microsoft.com/en-us/library/ms178104%28v=SQL.90%29.aspx qui donne des exemples et des informations sur la façon de déterminer l'origine de l'interblocage.

+0

Elles proviennent de différents spids sur le serveur et chaque processus ne peut être exécuté que par un seul utilisateur. – StingyJack

+0

Peut-être que nous devons définir "processus". Même avec des requêtes différentes par différents utilisateurs, vous pourriez toujours tomber dans des blocages. Par exemple, queryUser1 doit accéder aux données de A, B, C et queryUser2 doit accéder aux données de D, B, A. Si queryUser1 acquiert A, alors queryUser2 acquiert B, vous serez bloqué, car maintenant queryUser2 ne peut pas obtenir A pour continuer, et queryUser1 ne peut pas obtenir B pour continuer. – Nathan

+0

processus == travail. chaque processus/travail n'est exécuté que par un utilisateur à la fois. – StingyJack

0

Généralement cela se produit lorsque vous n'avez pas Dispose tous les objets jetables concernés, tels que Transaction s et Connection s.

+0

Dispose() est appelé là où la bibliothèque d'entreprise pense que c'est approprié, bien qu'il ait été connu pour avoir des bogues. – StingyJack

0

Qu'entendez-vous exactement par «transactions en série»? Deux transactions s'exécutant en série, ou deux transactions s'exécutant sous le niveau d'isolation de sérialisation? Est-ce que votre programme C# garantit d'exécuter un seul flux de travail à la fois, ou y a-t-il une concurrence entre deux instances du programme (commun dans ASP.Net, WCF, WF et bien d'autres scénarios de code hébergé)?

Une autre erreur courante serait si vous avez des étapes non validées dans le flux de travail. Say Step1 commence une transaction sur ConnecitonA, puis se termine sans commettre. Lorsque la logique passe à l'étape 2, exécute une nouvelle transaction sur ConnectionB, il peut s'agir d'un conflit et d'un interblocage avec le travail non engagé laissé par Step1. Ce serait le parallélisme réel dans la couche de base de données de l'exécution sérialisée complète dans le client.

Est-il possible que sql rapport que l'exécution est terminée, avant qu'elle ne est en réalité?

Pas

un verrou pourrait persister dans une transaction terminée ?

Pas (pour toutes les raisons pratiques, les verrous de la portée de la session appliquent uniquement à la base de données ou utiliser des verrous applocks).

Y a-t-il autre chose que je devrais regarder pour comprendre ce qui se passe?

Le serveur disposera de nombreux moyens pour résoudre ce problème. Entre Profiler, info graphique de blocage, sys.dm_exec_requests et sys.dm_tran_locks, toutes les informations dont vous avez besoin sont là.

+0

mise à jour post pour expliquer les transactions en série; série par opposition à parallèle – StingyJack

Questions connexes