2013-07-29 110 views
3

嗨我們已經開始使用事務範圍,下面是代碼片段。我們需要了解的是,基於我們在每次使用連接之後的特定連接將被處理/關閉的內容,因此,自從關閉transaction.complete以後如何工作?瞭解如何transaction.complete功能?

using (TransactionScope transScope = new TransactionScope()) 
{ 
    try 
    { 
     string myConnStringLocal = "User Id=***;Password=****;Host=" + globalSettings.settingLocalIP + ";Database=" + globalSettings.settingLocalDB; 
     using (MySqlConnection connectionLocal = new MySqlConnection(myConnStringLocal)) 
     { 
     try{ 
     connectionLocal.Open(); 
     } 
     Catch(Exception e) 
     { 

     } 
     finally{ 
     connectionLocal.Close(); 
     } 
     } 

     string myConnStringCentral = "User Id=***;Password=*****;Host=" + globalSettings.settingCentralIP + ";Database=" + globalSettings.settingCentralDB; 
     using (MySqlConnection connectionCentral = new MySqlConnection(myConnStringCentral)) 
     { 
     try{ 
     connectionCentral.Open(); 
     } 
     Catch(Exception e) 
     { 

     } 
     finally{ 
     connectionCentral.Close(); 
     } 

     } 
     string myConnStringCentralCopy = "User Id=*****;Password=*****;Host=" + globalSettings.settingCentralCopyIP + ";Database=" + globalSettings.settingCentralCopyDB; 
     using (MySqlConnection connectionCentralCopy = new MySqlConnection(myConnStringCentralCopy)) 
     { 
     try{ 
     connectionCentralCopy.Open(); 
     } 
     Catch(Exception e) 
     { 

     } 
     finally{ 
     connectionCentralCopy.Close(); 
     } 
     } 
     transScope.Complete(); 
     Console.WriteLine("Transaction is completed"); 
    } 
    catch (Exception) 
    { 
     Console.WriteLine("Transaction is rolled back"); 
    } 
} 
+0

您是否嘗試過實際運行代碼並查看發生了什麼? – vittore

+0

@是的,我嘗試了交易的作品,但我想了解它的細節。 – new14

回答

4

TransactionScope.Complete告訴所有的交易經理他們很好提交此交易。這不是一切都會實際承諾的保證。在完成方法被調用後,所有事務管理器都會單獨啓動一次提交,並且如果所有事務管理器都成功,則事務被視爲已成功完成。 你可以參考這個link for further details

+0

@所以,我的終極目標是如何保證所有人都會承諾?我的意思是在這種情況下如何確保分佈式事務的完整性?因此,在每個使用結束都沒有關閉連接之後,它將如何調用連接呢? – new14

+3

你永遠不能保證提交。交易的目的不是要保證所有的事情都不會保證任何事情都會承諾,或者什麼都不會承諾。 – Rwiti

+0

@因此,它的保證人不會是任何一個提交,它將會全部提交或不提交。那麼在使用block之後的連接可用性如何呢? – new14

-2
using (TransactionScope transScope = new TransactionScope()) 
    { 
     try 
     { 
      string myConnStringLocal = "User Id=***;Password=****;Host=" + globalSettings.settingLocalIP + ";Database=" + globalSettings.settingLocalDB; 
      using (MySqlConnection connectionLocal = new MySqlConnection(myConnStringLocal)) 
      { 
       connectionLocal.Open(); 
      } 

      string myConnStringCentral = "User Id=***;Password=*****;Host=" + globalSettings.settingCentralIP + ";Database=" + globalSettings.settingCentralDB; 
      using (MySqlConnection connectionCentral = new MySqlConnection(myConnStringCentral)) 
      { 
       connectionCentral.Open(); 
      } 
      string myConnStringCentralCopy = "User Id=*****;Password=*****;Host=" + globalSettings.settingCentralCopyIP + ";Database=" + globalSettings.settingCentralCopyDB; 
      using (MySqlConnection connectionCentralCopy = new MySqlConnection(myConnStringCentralCopy)) 
      { 
       connectionCentralCopy.Open(); 
      } 
      transScope.Commit(); 
      Console.WriteLine("Transaction is completed"); 
     } 
     catch (Exception) 
     { 
      transScope.RollBack(); 
      Console.WriteLine("Transaction is rolled back"); 
     } 
    } 
+1

你打算爲你的帖子添加任何解釋嗎?現在我甚至無法分辨您是否對發佈的內容做了任何更改。 –

+0

@我應該添加什麼類型的解釋請讓我知道incase我失蹤? – new14

+0

至少說出你改變了什麼,爲什麼改變了它。 –

2

Complete方法被調用,然後在範圍都將被提交,如果沒有Exception拋出。如果代碼在沒有Complete的情況下超出範圍,則不會發生提交。簡而言之,如果您致電Complete方法,那麼,如果沒有Exceptions被拋出,則在給定的TransactionScope範圍內的交易將被提交。

此外,我必須補充說,也可能有一個層次結構,一棵TransactionScopes的樹。您還可以爲TransactionScope的子範圍回滾時的情況設置TransactionScope的行爲。

2

當您連接到多個數據庫在一個TransactionScope,交易升級爲distributed事務協調使用2-phase commitMSDTC

關於連接關閉 - 當連接在TransactionScope內關閉時,在內部由基礎設施System.Transactions管理,所以特殊情況下,即使連接從您的端點關閉,數據庫會話仍然可以打開。

查看MSDN這樣一個字條:

未決交易使用Transact-SQL或調用BeginTransaction時,如果啓用了連接池的連接被重置自動回滾啓動。如果連接池關閉,則在調用SqlConnection.Close後,事務將回滾。交易開始通過System.Transactions的是通過System.Transactions的基礎設施控制,並且不會受到SqlConnection.Close

編輯根據您的意見,這裏是你可以做什麼:

try 
{ 
    using (TransactionScope transScope = new TransactionScope()) 
    { 
     string myConnStringLocal = ...; 
     using (var connectionLocal = new MySqlConnection(myConnStringLocal)) 
     { 
     connectionLocal.Open(); 
     // do your DB update 

     } //no need to close connection explicitly, the using() {..} statement does that for you 

     string myConnStringCentral = ...; 
     using (var connectionCentral = new MySqlConnection(myConnStringCentral)) 
     { 
     connectionCentral.Open(); 
     // do your DB update 

     } //no need to close connection explicitly, the using() {..} statement does that for you 

     string myConnStringCentralCopy = ...; 
     using (var connectionCentralCopy = new MySqlConnection(myConnStringCentralCopy)) 
     {   
     connectionCentralCopy.Open(); 
     // do your DB update 

     } //no need to close connection explicitly, the using() {..} statement does that for you 

     transScope.Complete(); 

     Console.WriteLine("Transaction is completed"); 

    } //no need to dispose transactionScope explicitly, the using() {..} statement does that for you 
} 
catch (Exception) 
{ 
     // If any exception occurs in the try block above transScope.Complete() line will be caught here 
     // and will automatically cause the transaction to rollback. 
     Console.WriteLine("Transaction is rolled back"); 
} 

// You can then start new TransactionScope if you want to further update more than one DB in a transactional manner. 
try 
{ 
    using (TransactionScope transScope = new TransactionScope()) 
    { 
     //... 

    } 
} 
catch (Exception) 
{ 
    //... 
} 
+0

是的,這是我正在尋找的原因,如果你看到我的問題,我已經用try和catch進一步更新它,最後單獨關閉連接。那很好嗎?你可以在我的問題中查看代碼是否正確? – new14

+0

@ new14:如果你有'using(.. myconn ...){..}' - 因爲'using'語句編譯爲'try/finally',所以沒有必要在'finally'塊中明確地關閉連接。阻止並自動調用finally塊中的連接上的'Dipose' - 'Dispose' inturn將調用'Close'。 – YK1

+0

try/finally的編譯在哪裏,因爲我們看不到它是正確的?這裏我不太清楚,請進一步描述。 – new14