2016-11-10 2 views
1

Considérant ce morceau de code:La transaction C# avec l'exception gérée sera toujours annulée?

using(TransactionScope tran = new TransactionScope()) { 

    insertStatementMethod1(); 
    insertStatementMethod2(); 
    // this might fail 
    try { 
     insertStatementMethod3(); 
    } catch (Exception e) { 
     // nothing to do 
    } 

    tran.Complete(); 
} 

est-il quoi que ce soit fait dans insertStatementMethod1 et insertStatementMethod2 va être annulée? Dans tout les cas? Si je veux qu'ils s'exécutent de toute façon, je devrais vérifier si insertStatementMethod3 échouera avant la transaction et construire mon code de transaction basé sur cela?

Mise à jour

Le code ressemble à ce

using(TransactionScope tran = new TransactionScope()) { 
    // <standard code> 
    yourExtraCode(); 
    // <standard code> 
    tran.Complete(); 
} 

où je reçois d'écrire la méthode yourExtraCode()

public void yourExtraCode() { 
    insertStatementMethod1(); 
    insertStatementMethod2(); 

    // this call might fail 
    insertStatementMethod3(); 
} 

je ne peux modifier la méthode yourExtraCode(), donc je ne peux pas a choisi d'être dans la portée de la transaction ou non. Une solution simple possible serait la suivante:

public void yourExtraCode() { 
    insertStatementMethod1(); 
    insertStatementMethod2(); 

    // this call might fail 
    if (findOutIfIcanInsert()) { // <-- this would come by executing sql query 
     try { 
      insertStatementMethod3(); 
     } catch (Exception e) { 
      // nothing to do 
     } 
    } 
} 

Mais cela viendrait avec la nécessité de chercher des choses dans la base de ce qui aurait une incidence sur la performance. Existe-t-il un meilleur moyen, ou je dois savoir avant d'appeler la méthode? J'ai essayé et, bien sûr, la transaction a été annulée comme prévu.

+0

check this http://stackoverflow.com/questions/494550/how-does-transactionscope-roll-back-transactions –

+1

En fait vous avez la possibilité de choisir de ne pas faire partie d'une transaction ambiante, voir ma réponse ci-dessous. –

Répondre

1

Si vous ne voulez pas que vos deux premières méthodes soient traitées, il suffit de les sortir de la portée de la transaction ambiante.

Si vous n'avez aucun contrôle sur le code qui déclenche une transaction ambiante, vous pouvez le supprimer en créant une nouvelle transaction ambiante: using (var scope = new TransactionScope(TransactionScopeOption.Suppress)).

+0

Mon exemple est un peu simplifié. En fait, je peux écrire une méthode qui était déjà appelée dans une transaction. Je n'ai pas le contrôle de l'endroit où la portée commence et se termine, mais je peux écrire si des déclarations autour de mes appels. Cependant cela viendra avec des requêtes SQL affectant ainsi les performances. – DDan

+0

Réponse positive –