2010-08-13 5 views
2

J'ai un serveur d'application C# ASP .Net n-tier qui utilise des procédures stockées pour communiquer avec la base de données.Validation de transaction isolée dans SQL

J'ai une couche de service qui annule toutes les transactions ADO .net si une exception est levée, en utilisant TransactionScope.requiresNew.

Dans ma procédure stockée, je souhaite effectuer le suivi des numéros de tentatives de connexion. Nous souhaitons donc conserver le cadre de transaction tel quel, mais nous souhaitons effectuer une transaction isolée que nous engageons.

Comment faire?

J'ai essayé d'utiliser un nouveau TransactionScope.RequiresNew dans notre couche de données, mais cela n'a aucun effet.

Répondre

0

Strange - RequiresNew dans le TransactionScope interne (Logging) devrait fonctionner.

Dans la transaction imbriquée ci-dessous, TransactionScopeOption.Suppress ou TransactionScopeOption.RequiresNew fonctionnent tous les deux pour moi: la transaction interne est validée (Dal2.x) et la transaction externe est annulée (Dal1.x).

try 
    { 
     using (TransactionScope tsOuter = new TransactionScope(TransactionScopeOption.Required)) 
     { 
      DAL1.Txn1(); 
      using (TransactionScope tsLogging = new TransactionScope(TransactionScopeOption.Suppress)) 
      { 
       DAL2.Txn2(); 
       tsLogging.Complete(); 
      } 
      throw new Exception("Big Hairy Exception"); 
     } 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 

Edit: mélange TransactionScope et transactions T-SQL explicites doit être évité - cela est indiqué dans le même lien que vous avez parlé à savoir http://msdn.microsoft.com/en-us/library/ms973865.aspx, cité ci-dessous

TransactionScopes gérer l'escalade des transactions tout à fait intelligemment - ils utilise DTC (par exemple DTC ne sera utilisé que si les transactions couvrent plusieurs bases de données ou ressources - par exemple SQL et MSMQ). Ils fonctionnent également avec les transactions SQL 2005+ Lightweight, de sorte que plusieurs connexions à la même base de données seront également gérées dans une transaction sans les frais généraux de DTC. À mon humble avis, la décision d'utiliser Suppress vs RequiresNew dépendra de si vous avez besoin de faire votre audit dans une transaction du tout - RequiresNew pour un txn isolé, vs Suppress for none.

Lors de l'utilisation System.Transactions, applications ne doivent pas directement utiliser la programmation transactionnelle interfaces ressources gestionnaires pour exemple le T-SQL BEGIN TRANSACTION ou COMMIT verbes TRANSACTION, ou l'objet MessageQueueTransaction() dans Espace de noms System.Messaging, lorsque traitant de MSMQ. Ces mécanismes éviteraient la gestion distribuée des transactions traitées par System.Transactions, et en combinant l'utilisation de System.Transactions avec ces gestionnaire de ressources « interne » transactions conduiront à incompatibles les résultats .... Ne jamais mélanger les deux

+0

Bonjour @nonnb, merci pour cela. Qu'est-ce que je suppose censé faire? – Russell

+0

Après un peu de lecture (http://msdn.microsoft.com/en-us/library/ms973865.aspx), Suppress n'a aucune transaction du tout. Il n'utilise pas non plus la transaction ambiante qui est ce que je veux. Je ne sais pas si je préférerais une transaction ou non. J'en ai un dans ma procédure stockée (BEGIN TRANSACTION, COMMIT) ... – Russell

+0

Salut Russell - J'ai édité mon post original car mon commentaire était trop gros. Si tu peux. Comme il semble que vous ayez une stratégie pour contrôler les transactions à partir de votre code .NET (par exemple Service ou Business Tiers), nous vous recommandons de supprimer BEGIN TRAN/COMMIT TRAN de vos sprocs - TransactionScope le remplace. – StuartLC

Questions connexes