2016-11-10 103 views
1

考虑这段代码:处理异常的C#事务仍然会回滚?

using(TransactionScope tran = new TransactionScope()) { 

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

    tran.Complete(); 
} 

是什么,在insertStatementMethod1insertStatementMethod2打算做回滚?任何状况之下? 如果我想让它们执行,我需要检查它是否会在事务之前失败,并基于此建立我的事务代码?

更新

的代码类似于此

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

在那里我去写yourExtraCode()方法

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

    // this call might fail 
    insertStatementMethod3(); 
} 

我只能编辑yourExtraCode()方法,所以我不能选择了在交易范围还是没有。一个简单可行的办法是这样的:

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 
     } 
    } 
} 

但是,这将伴随着需求,其中会影响性能的数据库中查找的东西。 有没有更好的方法,或者我需要在调用方法之前找出答案? 我试过了,当然事务按预期回滚了。

+0

检查此问题http://stackoverflow.com/questions/494550/how-does-transactionscope-roll-back-transactions –

+1

实际上,您有可能选择不成为环境交易的一部分,请参阅下面的答案。 –

回答

1

如果您不想要前两个方法进行事务处理,只需将它们从环境事务的范围中移出即可。

如果您无法控制启动环境事务的代码,则可以通过创建新环境事务来禁止它:using (var scope = new TransactionScope(TransactionScopeOption.Suppress))

+0

我的例子有点简化。其实我已经写了一个在交易中被调用的方法。我无法控制范围的开始和结束位置,但我可以在我的呼叫周围编写语句。但是,SQL查询将会影响性能。 – DDan

+0

答复uptdated –