2012-08-14 21 views
1

我想在多個進程後使用Rollback()或commit()函數。Asp.net c#,多個進程後的回滾或提交

沒有錯誤,但它沒有提交()來更新數據庫。

這裏是我的示例代碼,

public void startTransaction(){ 
    using(Ads_A_Connection = new AdsConnection(Ads_A_connection_string)) 
    using(Ads_B_Connection = new AdsConnection(Ads_B_connection_string)) 
    { 
     Ads_A_Connection.Open(); 
     Ads_B_Connection.Open(); 

     AdsTransaction aTxn = Ads_A_Connection.BeginTransaction(); 
     AdsTransaction bTxn = Ads_B_Connection.BeginTransaction(); 

     try{ 
      string aResult = this.process1(Ads_A_Connection);  
      this.process2(Ads_B_Connection, aResult);  
      this.process3(Ads_A_Connection. Ads_B_Connection); 

      aTxn.Commit(); 
      bTxn.Commit(); 
      // there is no error, but it couldn't commit. 
     }catch(Exception e){ 
      aTxn.Rollback(); 
      bTxn.Rollback(); 
     } 
    } 
} 

public string process1(conn){ 
    // Insert data 
    return result; 
} 

public void process2(conn. aResult){ 
    // update 
} 

public void process3(aConn, bConn){ 
    // delete 
    // update 
} 

我猜想,因爲它使用了範圍。因爲我試圖把所有的代碼放入 startTransaction()方法,那麼它就可以工作。但它看起來太髒了。

如何在多個(METHOD)過程之後使用rollback()或commit()?

有人知道,請指教我。

謝謝!

[編輯]

我只是連接之前添加的TransactionScope,

using (TransactionScope scope = new TransactionScope()) 
{ 
    using(Ads_A_Connection = new AdsConnection(Ads_A_connection_string)) 
    using(Ads_B_Connection = new AdsConnection(Ads_B_connection_string)) 
    { 
    . 
    . 

但它是一個錯誤,它說: 「錯誤5047:該交易指令不在有效序列。」

我需要多一點提示,請:) :)

+0

然後外部事務 – 2012-08-14 14:01:07

+1

再一次提交的內/嵌套事務:5047 - 你刪除連接上的手動BeginTransaction(),Commit()和Rollback()?這現在由TransactionScope管理。 – StuartLC 2012-08-14 14:34:37

回答

2

要擴展什麼蝕刻提到,他們的幾個問題與您聯繫手動管理交易:

  • 你需要繞過你的方法SQL連接
  • 需要手動記在完成時提交或回滾
  • 如果您有多個連接要在事務下管理,那麼您應該使用DTC或XA將事務註冊到分佈式/ 2階段事務。

TransactionScopes are supported與優勢數據庫服務器,雖然你將需要啓用MSDTC service,可能也使XA達標。

請注意,我假設.NET客戶端具有某種連接池機制的優點 - 這使得獲取連接的成本非常輕。

最終,這意味着你的代碼可以被重構爲類似於以下,這是更易於維護:

private void Method1() 
{ 
    using(Ads_A_Connection = new AdsConnection(Ads_A_connection_string)) 
    { 
     Ads_A_Connection.Open(); 
     string aResult = this.process1(Ads_A_Connection);  
    } // Can logically 'close' the connection here, although it is actually now held by the transaction manager 
} 

private void Method2() 
{ 
    using(Ads_B_Connection = new AdsConnection(Ads_B_connection_string)) 
    { 
     Ads_B_Connection.Open(); 
     this.process2(Ads_B_Connection, aResult);  
    } // Can logically 'close' the connection here, although it is actually now held by the transaction manager 
} 


public void MyServiceWhichNeedToBeTransactional(){ 
    using(TransactionScope ts = new TransactionScope()) { // NB : Watch isolation here. Recommend change to READ_COMMITTED 
     try{ 
      Method1(); 
      Method2(); 
      ts.Complete(); 
     } 
     catch(Exception e){ 
      // Do Logging etc. No need to rollback, as this is done by default if Complete() not called 
     } 
    } 
} 
+0

using System.Transactions; (C:\ Program Files(x86)\ Reference Assemblies \ Microsoft \ Framework \ .NETFramework \ v4.5 \ System.Transactions.dll) – 2012-09-13 14:46:24