2008-12-04 6 views
0

Je suis en train d'utiliser System.Transaction.TransactionScope pour créer une transaction pour appeler quelques procédures stockées, mais il ne semble pas nettoyer après lui-même. Une fois la transaction terminée (commited ou non, et l'objet de la portée de la transaction est disposé) des connexions suivantes à la base de données ouverte avec la lecture niveau validation de sérialisable au lieu de lire comme ils le feraient commited normalement.System.Transaction transaction implicite déconner avec mes autres connexions

Je suis l'ouverture et la fermeture d'une connexion pour chaque appel (fermeture de puits et retour à un pool de connexions comme normal dans .NET), suis-je manquant un moyen de réinitialiser explicitement la connexion lorsque je l'utilise une transaction? Je pensais que l'idée derrière System.Transaction.TransactionScope était de cacher toute la complexité.

Ainsi, le code que j'ai ressemble à ceci:

  using (var scope = new TransactionScope()) 
      { 
       ... make my 3 stored procedure calls ... 

       scope.Complete(); 

       return returnCode; 
      } 

que je suppose est la façon normale de le faire. Mais si je regarde dans profileur SQLServer Je peux voir les connexions en cours d'ouverture avec

set transaction isolation level serializable 

qui salit l'activité ultérieure de base de données non liées à la transaction et est aussi apparemment pas aussi vite. Je peux contourner cela en définissant une option de transaction explicite pour faire la transaction avec ReadCommited mais ce n'est pas le comportement idéal pour cette opération à mon avis.

J'ai aussi essayé de créer explicitement un objet Commitabletransaction, ce qui crée des transactions explict nouvelles au lieu d'utiliser une ambiante et toujours pas de chance.

Toutes les idées sur la façon de résoudre ce problème serait très apprécié que tous les appels qui utilisent la connexion sérialisable jetteront une erreur s'ils essaient d'utiliser une touche de verrouillage READPAST.

Répondre

0

Vous devriez également voir une remise à zéro (sp_reset_connection) entre les utilisations de la même connexion dans la piscine; cela ne réinitialisera-t-il pas le niveau d'isolation? Avez-vous essayé de reproduire un problème sérialisable (par exemple, interblocages escalade de verrous)

+0

Je vois vraiment la connexion sp_reset.Je peux franchir et voir chaque connexion explicitement fermée. Comment voulez-vous dire reproduire un problème sérialisable? Je suis le seul à utiliser le système lorsque j'essaie de le faire et je n'ai aucun blocage (vérification de trace sur le profileur et la journalisation des transactions) – mjallday

+0

Ce que je veux dire est: vous prétendez qu'il interfère avec "l'activité de base de données non liée à la transaction suivante" ; Je dis: "êtes-vous sûr?". Je soupçonne que sp_reset_connection signifie que l'activité db suivante n'est pas affectée par ce niveau d'isolation. –

+0

Pour vérifier à coup sûr, vous devrez vérifier si les verrous supplémentaires sont prises. Une option est un scénario d'escalade de verrou - c'est-à-dire que spid A lit une ligne (sans UPDLOCK), spid B lit une ligne, A essaie de mettre à jour la ligne, B essaie de mettre à jour la ligne. Si cela se bloque, les spids sont sérialisables. –

1

Utilisez TransactionOptions.IsolationLevel

Par default, it's serializable

TransactionOptions transactionoptions1 = new TransactionOptions(); 
transactionoptions1.IsolationLevel = IsolationLevel.ReadCommitted; 
using (var scope = new TransactionScope(TransactionScopeOption.Required, transactionoptions1)) 
{ 
    ... make my 3 stored procedure calls ... 

    scope.Complete(); 

    return returnCode; 
} 
+0

C'est la solution actuelle que j'ai utilisée pour contourner le problème. Mais je m'intéresse à la raison pour laquelle je vois le comportement que je vois. Les appels db ultérieurs ne devraient sûrement pas utiliser le niveau d'isolation de la transaction? – mjallday

0

C'est une décision de conception connue dans SQL Server.

En outre, using new TransactionScope() Considered Harmful (06/2010; éviter constructeur par défaut)

Questions connexes