2010-06-22 29 views
0

我正在使用SqlDataAdapter.Update與DataTables更新一個事務中的兩個SQL表。如果插入失敗,我想回滾所有數據。這是我的代碼:TransactionScope不回滾與SqlDataAdapter.Update

using (var conn = new SqlConnection(_connectionString)) 
{ 
    conn.Open(); 

    using (var scope = new TransactionScope()) 
    { 
     // Insert first table 
     using (var command = conn.CreateCommand()) 
     { 
      command.CommandText = 
       @"INSERT INTO TableA(Id, Data) 
        VALUES(@id, @data)"; 

      command.CommandType = CommandType.Text; 
      command.Parameters.Add(new SqlParameter("@id", SqlDbType.Int) { SourceColumn = "Id" }); 
      command.Parameters.Add(new SqlParameter("@data", SqlDbType.Char) { SourceColumn = "Data" }); 

      var adapter = new SqlDataAdapter(); 
      adapter.InsertCommand = command; 
      adapter.Update(tableADataTable); 
     } 

     // Insert second table 
     using (var command = conn.CreateCommand()) 
     { 
      command.CommandText = 
       @"INSERT INTO TableB(Id, Data) 
        VALUES(@id, @data)"; 

      command.CommandType = CommandType.Text; 
      command.Parameters.Add(new SqlParameter("@id", SqlDbType.Int) { SourceColumn = "Id" }); 
      command.Parameters.Add(new SqlParameter("@data", SqlDbType.Char) { SourceColumn = "Data" }); 

      var adapter = new SqlDataAdapter(); 
      adapter.InsertCommand = command; 
      adapter.Update(tableBDataTable); 
     } 

     scope.Complete(); 
    } 
} 

我遇到的問題是,如果一個例外是第二個命令執行過程中引發的,從第一個命令數據仍COMMITED。我是否需要明確回滾?或者當使用SqlDataAdapter.Update時,TransactionScope應該如何表現?

需要注意的是,最初我在TransactionScope using語句中創建了SqlConnection,但是當我收到錯誤時,我的數據庫服務器沒有正確配置分佈式事務。是否我的SqlConnection創建與TransactionScope相關?

回答

1

嘗試將您的SqlConnection放入TransactionScope中,然後它應該自動登記到事務中。

我認爲在您的代碼中,您需要手動將連接加入事務中...查看這些鏈接中的示例。

http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.enlistdistributedtransaction(v=VS.71).aspx

http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx

對不起剛好趕上你的OP - 也許是因爲連接未配置爲自動登記到現有的交易(連接字符串我想的成員)。

如果您沒有調用Complete(或在SqlTransaction上提交),它會自動回滾。

當然,在您當前的代碼示例中 - 您可以安全地使用SqlTransaction對象,因爲您不涉及多個連接/數據庫。

2

我認爲您需要將您的conn.Open()調用移入事務範圍內,以便它自己進入事務。另外,請確保您的連接字符串中沒有enslist=false;

0

嘗試插入碼

command.CommandText = @"SET autocommit = 0"; 
command.ExecuteNonQuery(); 

command.CommandText = @"SET sql_mode=TRADITIONAL"; 
command.ExecuteNonQuery(); 
相關問題