2009-11-18 4 views
6

Je commence tout juste à travailler avec TransactionScope, je trouve qu'il y a toujours des choses inattendues que je rencontre et qui mettent un temps infini à déboguer. Je pense qu'ayant une liste consolidée de ceux-ci serait génial pour ces circonstances «d'erreur bizarre», plus pour élargir nos connaissances de l'étrangeté dans la plate-forme.Généralités lors de l'utilisation de TransactionScope et MS DTC

un contexte sur la façon dont je vais utiliser les étendues de transaction:

  • application web
  • plusieurs serveurs Web, serveurs d'applications et les serveurs SQL
  • transactions seront des transactions de base de données principalement, mais certains seront élevé pour écrire à MSMQ.

Répondre

3

2 choses du haut de ma tête:

  • transactions seront élevés lorsque vous utilisez plus d'un objet de connexion dans la même portée, même si les connexions ont la même connectionstring (ce qui est fixe en sql 2008). En savoir plus dans this thread et dbconnectionscope résoudra ce problème sur SQL 2005
  • cas MSDTC doivent être en mesure de voir et doivent avoir leur sécurité mis en place correctement http://support.microsoft.com/kb/899191 (permettre entrants et sortants, ne nécessitent pas d'authentification mutuelle est généralement le pari le plus sûr). Utilisez DTCPing pour résoudre les problèmes de connexion entre les instances dtc comme expliqué ici: http://support.microsoft.com/kb/306843

Vous voulez des transactions d'être léger, autant que possible, dtc introduit beaucoup de frais généraux. Vous souhaitez également que les transactions soient aussi courtes que possible, ne les introduisez donc que sur les serveurs d'applications et non sur le serveur Web. Faire le saut sur le réseau entre les serveurs d'applications et la base de données aussi petit que possible et aussi vite que possible, envoyer le trafic réseau entre les serveurs Web et App sur une connexion différente entre serveurs d'applications et db, et faire le dernier cri rapidement , connexion ridiculement courte. Si vous avez plusieurs serveurs d'applications, vous pouvez envisager d'avoir une seule instance de msdtc en cours d'exécution sur un serveur (par exemple sur la base de données ou sur l'un des serveurs d'application) et l'utiliser à distance de tous les serveurs d'applications. leur propre, mais je ne sais pas quels avantages supplémentaires cela a.

+1

Est-il vraiment corrigé dans SQL Server 2008? J'utilise SQLS2008 et lorsque j'ouvre une deuxième connexion avec la même chaîne de connexion, la transaction obtient un GUID distribué. Alors ... est-ce seulement du côté des clients, ou est-ce vraiment une transaction distribuée? – Triynko

+0

Voir http://msdn.microsoft.com/fr-fr/library/ms172070%28VS.90%29.aspx Je ne l'ai pas testé pour moi-même, mais selon les docs, il devrait y avoir au moins un scénario plausible où SQL 2008 se comporte comme ça. Peut-être que modifier votre connexiontring pour contrôler explicitement la mise en commun pourrait vous aider. – stombeur

+1

Ne semble pas résolu avec SQL Server 2008, voir transaction élevée à DTC avec la même chaîne de connexion et la base de données locale – mamu

-2

Si vous utilisez SQL Server et vérifier @@ trancount, il sera 0 même si vous avez un TransactionScope actif.

+1

Ce ne sera pas zéro; Je viens de le tester. Vous ouvrez probablement votre connexion avant l'étendue de la transaction, ce qui signifie que votre connexion ne participe pas du tout à la transaction (quelque chose que je viens d'apprendre, voir mon article ici: http://stackoverflow.com/questions/2884863/under-what -circumstances-is-an-sqlconnection-automatiquement-enrôlé-dans-un-ambient/2886326 # 2886326). Vous pouvez soit ouvrir votre connexion à l'intérieur de la portée de la transaction, soit inscrire explicitement votre transaction existante dans la portée en appelant connection.EnlistTransaction (Transaction.Current). Exécutez "select @@ trancount" pour voir son non-zéro. – Triynko

1

Notez également que si vous modifiez l'un de vos objets au cours de la transaction, ils ne seront pas annulés à moins que vous n'ayez ajouté du code pour gérer cela.

Voir TransactionScope and rolling back object state

+0

Quoi? Si vous parlez d'objets de base de données, ce n'est pas vrai. Si vous émettez des commandes sur une connexion inscrite dans la portée de la transaction, et que vous ne la validez pas, lorsque la portée est éliminée, les modifications sont annulées ... comme toute autre transaction. Si vous parlez d'objets non-base de données, comme les fichiers et les variables d'application, alors oui ... car ils n'ont rien à voir avec la transaction. – Triynko

+0

J'ai eu un comportement très bizarre en utilisant 'TransactionScope' et DDL - j'ai dû me débarrasser de' TransactionScope' et utiliser des transactions normales et explicites pour le réparer. – Lucero

0

Espérons que cela vous aidera un jour quelqu'un:

Si vous avez un TransactionScope avec plusieurs opérations SQL à l'intérieur, le DTC ne sera pas impliqué fourni

  1. vous utilisez identiques Chaîne de connexion pour chaque connexion
  2. Les connexions ne sont pas imbriquées.

I.e. ouvrir, faire quelque chose, fermer. ouvrir, faire quelque chose, fermer.

Maintenant, pour la chasse aux sorcières: si vous ne jamais dans votre processus (sur un autre thread)

SqlConnection.ClearAllPools()

et qui arrive à venir entre vos deux opérations - le DTC sera impliqué immédiatement. Si le DTC n'est pas en cours d'exécution, une exception sera émise.

Questions connexes