2011-09-09 11 views
0

我在應用程序中使用不同的SQL過程。 首先在C#代碼中插入一些行然後再進行一些處理然後第二個程序 再做一些更新然後再進行一些代碼處理然後第三個程序刪除一些記錄然後插入新的記錄。當所有操作都在服務器1上完成時,則從該服務器獲取數據並將其發送到服務器2,並刪除記錄並插入新記錄。 如果在任何服務器的任何階段出現錯誤,我想要回滾所有記錄。 我無法使用開始轉換,因爲處理需要時間並且不能阻止表,因爲其他用戶也同時使用相同的表。所以請告訴我如何在不阻止其他用戶的表的情況下實現它。如何在出現任何錯誤時在不同數據庫服務器上回滾多個查詢

在此先感謝。

已編輯(添加代碼示例): 我試過了事務範圍,但在打開連接時出現異常。我配置了MS DTC,但可能配置不正確。

網絡訪問分佈式事務管理器(MSDTC)已被禁用。請啓用DTC在使用MSDTC組件服務管理工具安全配置網絡訪問。」

using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required)) 
    { 


     try 
     { 
      dl.SetBookReadyToLive(13570, false); 
      //SetBookReadyToLive 
      dl.AddTestSubmiitedTitleID(23402); 
      dl.AddBookAuthorAtLIve(13570, 1); 
      ts.Complete(); 

     } 
     catch (Exception ex) 
     { 
      Response.Write(ex.Message); 
     } 
    } 

公共無效SetBookReadyToLive(長的BookID,布爾狀態) { 嘗試 { 如果(dbConMeta.State = ConnectionState.Open!) dbConMeta.Open();

  SqlCommand cmd = new SqlCommand("spSetBookReadyToLive", dbConMeta); 
      cmd.CommandType = CommandType.StoredProcedure; 
      cmd.Parameters.Clear(); 
      cmd.Parameters.Add("@BookID", BookID); 
      cmd.Parameters.Add("@status", status); 
      cmd.ExecuteNonQuery(); 
      if (dbConMeta.State == ConnectionState.Open) 
       dbConMeta.Close(); 

     } 
     catch 
     { 
      if (dbConMeta.State == ConnectionState.Open) 
       dbConMeta.Close(); 

     } 

    } 

我得到的異常上打開方法的連接>

我使用SQL Server 2000中,我已經設置好安裝SQL Server MS DTC的機器上的配置,並在我的電腦我從哪裏運行代碼。但同樣的例外。

請幫助我配置它

回答

1

您可以使用TransactionScope類。它通常工作得很好,但在分佈式SQL服務器的情況下,就像在您的情況下一樣,需要在兩臺服務器中啓用MS DTC並進行正確配置(必須授予執行網絡事務的安全性,分佈式等等......)

這裏從MSDN的例子的複製粘貼,你可以「差不多」這樣使用它... :)

// 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(); 

} 

來源:TransactionScope Class

,以儘量減少鎖,你可以與過載指定的IsolationLevel採用TransactionScopeOptions的構造函數,如果你使用的話,默認是Serializable沒關係,你可以將它設置爲ReadCommitted。

注:我個人不會使用這個,除非絕對需要,因爲有DTC總是配置和分佈式事務通常比本地慢,但真的取決於你的BL/DAL邏輯。

+0

感謝大衛的幫助。在上面發佈的原始問題中發佈了示例代碼。我使用了交易範圍。但在權限中出現錯誤。我在客戶機和服務器上配置了MS DTC,但仍然出現錯誤。請再次參閱上述文章。請幫助我。再次感謝> –

+0

拜託你幾乎沒有!只是谷歌有點爲您的錯誤信息,你會發現一步一步的指導如何設置ms dtc啓動和運行的頁面。網絡錯誤是最常見的,只需觸摸安全設置中的最後一件事。對不起,我不記得壁爐旁的東西。 –

0

簡答:如果您想在MS SQL Management Studio中執行此操作,您可以採用同樣的方法。

  1. 您打開到服務器的連接。
  2. 打開特定服務器的交易
  3. 您運行與此相關的服務器查詢
  4. 你一定要保持你的連接還活着,而你... [回1。下一個服務器]

如果您的所有查詢都有效,請提交所有更改。 否則,回滾您的所有查詢。

警告:在您完成所有服務器/查詢之前,第一個表格很可能會被鎖定。你可以做這裏是爲了幫助這樣的:如果你有大量的數據,你可以做第2步之前每次傳輸服務器上的數據到臨時表。一旦完成,您可以打開事務,快速執行任務,然後儘快執行/回滾。

注:我知道你問如何實現這一目標不鎖定表,因此,爲什麼我添加在«警告»一部分的想法。

相關問題