2010-08-21 82 views
6

我看過System.Transactions命名空間,並且想知道,我是否可以使用這個名稱空間的用法來創建一個RDMBS?什麼是System.Transactions的實際用途?

但是當我看到一些例子時,我不明白System.Transactions是如何進行超越簡單的嘗試捕獲並獲得成功/失敗結果的東西的?

這是MSDN網站上的示例,我知道它可能很簡單,但我無法理解此示例中的好處,有人能告訴我下面的示例中簡單try/catch和Transaction scope之間的區別。

如果我要創建一個RDBMS(創建自己的RDMBS),我知道我們必須將很多日誌寫到我們執行的操作的磁盤上,最後我們在回滾的情況下撤消這些操作,但是這裏沒有任何關於撤銷任何東西。

// This function takes arguments for 2 connection strings and commands to create a transaction 
// involving two SQL Servers. It returns a value > 0 if the transaction is committed, 0 if the 
// transaction is rolled back. To test this code, you can connect to two different databases 
// on the same server by altering the connection string, or to another 3rd party RDBMS by 
// altering the code in the connection2 code block. 
static public int CreateTransactionScope(
    string connectString1, string connectString2, 
    string commandText1, string commandText2) 
{ 
    // Initialize the return value to zero and create a StringWriter to display results. 
    int returnValue = 0; 
    System.IO.StringWriter writer = new System.IO.StringWriter(); 

    try 
    { 
     // Create the TransactionScope to execute the commands, guaranteeing 
     // that both commands can commit or roll back as a single unit of work. 
     using (TransactionScope scope = new TransactionScope()) 
     { 
      using (SqlConnection connection1 = new SqlConnection(connectString1)) 
      { 
       // Opening the connection automatically enlists it in the 
       // TransactionScope as a lightweight transaction. 
       connection1.Open(); 

       // Create the SqlCommand object and execute the first command. 
       SqlCommand command1 = new SqlCommand(commandText1, connection1); 
       returnValue = command1.ExecuteNonQuery(); 
       writer.WriteLine("Rows to be affected by command1: {0}", returnValue); 

       // If you get here, this means that command1 succeeded. By nesting 
       // the using block for connection2 inside that of connection1, you 
       // conserve server and network resources as connection2 is opened 
       // only when there is a chance that the transaction can commit. 
       using (SqlConnection connection2 = new SqlConnection(connectString2)) 
       { 
        // The transaction is escalated to a full distributed 
        // transaction when connection2 is opened. 
        connection2.Open(); 

        // Execute the second command in the second database. 
        returnValue = 0; 
        SqlCommand command2 = new SqlCommand(commandText2, connection2); 
        returnValue = command2.ExecuteNonQuery(); 
        writer.WriteLine("Rows to be affected by command2: {0}", returnValue); 
       } 
      } 

      // The Complete method commits the transaction. If an exception has been thrown, 
      // Complete is not called and the transaction is rolled back. 
      scope.Complete(); 

     } 

    } 
    catch (TransactionAbortedException ex) 
    { 
     writer.WriteLine("TransactionAbortedException Message: {0}", ex.Message); 
    } 
    catch (ApplicationException ex) 
    { 
     writer.WriteLine("ApplicationException Message: {0}", ex.Message); 
    } 

    // Display messages. 
    Console.WriteLine(writer.ToString()); 

    return returnValue; 
} 

在上面的例子中,我們提交了什麼?我猜SQL客戶端庫會做一切正確的?這是否意味着System.IO.StringWriter將包含所有成功文本或所有失敗文本?或者在TransactionScope的範圍之間是否存在任何鎖定?

+0

你是什麼意思的「使RDBMS」? – nos 2010-08-21 09:56:52

+0

關係數據庫管理系統,SQL Server或MySQL或Oracle的副本,我的意思是如果我想在.net上創建自己的XYZSql數據庫系統,那麼我可以使用它嗎? – 2010-08-21 10:03:47

+1

並非如此,但如果您的新XYZSql數據庫系統支持事務,則可以在您的.NET XYZSql ADO.NET驅動程序中實現對System.Transactions的支持。 – nos 2010-08-21 10:12:29

回答

3

首先,TransactionScope與try/catch不同。 TransactionScope是由一個事務的名稱範圍。範圍內的事務必須通過在範圍上調用Complete來顯式提交。任何其他情況(包括在範圍中引發的異常)都會導致使用塊來完成,該塊將處理作用域並隱式回滾未完成的事務,但不會處理異常。

在基本情況下,來自System.Transactions的事務與db客戶端事務的行爲相同。 System.Transactions提供以下附加功能:

  • API不可知。您可以爲oracle,sql server或web服務使用相同的事務範圍。當你的事務開始於持久性無知的層(不知道持久性實現的任何信息)時,這一點很重要。
  • 自動登記。如果在連接字符串上指定(默認行爲)。新的數據庫連接會自動登錄到現有的事務中。
  • 自動升級爲分佈式事務。當第二個連接進入事務處理時,它將自動提升爲分配的一個(需要MSDTC)。當您爭取其他協調資源(如事務性Web服務)時,促銷也會有效。
1

交易將爲您做必要的鎖定。此外,如果事務在其範圍的末尾處被處置(如果未由Complete()提交)(如評論所建議的),則存在隱式回滾。因此,如果發生異常,所有操作都會自動回滾,並且不會在數據庫中發生更改。例如,如果第二個查詢失敗,它也會使第一個查詢的更改被丟棄。

然而,對於StringWriter的,它仍然會包含一些消息,直至故障點(例如

Rows to be affected by command1: {0} 
ApplicationException Message: {0} 

既可以此代碼後,會出現在你的日誌。

作爲創建與RDBMS如果你想真正創建一個關係數據庫管理系統,我會說你可能看錯了地方,如果你的意思是你想通過事務訪問RDBMS,我想說,這取決於你的需求,也就是說,如果你需要交易,可以保證你的報表能夠運行訂單和全部或全部的方式,那麼是的,交易是一個開始的好地方。

+0

是的,我打算創建RDBMS,不使用一個,我知道我可以使用數據庫客戶端庫事務,如SqlTransaction等,但我仍然不明白你的意思是必要的鎖定,因爲,我看到這樣,即使我不要在這裏使用TransactionScope,我仍然會得到相同的結果,如果任何命令會失敗的權利? – 2010-08-21 10:06:20

+0

對不起再次打擾,你的意思是即使我沒有明確地在這段代碼中使用SqlTransaction,System.Transactions會隱式撤消對Sql數據庫所做的更改嗎?這意味着Sql Client Library會自動創建一個SqlTransaction的實例並使用它,所以當我可以直接使用SqlTransaction時,實際上沒有使用System.Transactions? – 2010-08-21 10:09:03

+0

TransactionScope是對SqlTransaction的一種抽象,它可以跨越SqlTransaction,e,g,MSMQ事務等其他事物。 – nos 2010-08-21 10:15:04

相關問題