2013-10-17 90 views
1

我有複製從一臺服務器的數據到不同的服務器下面的代碼:無法ROLLBACK TRANSACTION:這的SqlTransaction已完成

private static string CopyData(string sourceConnection, string targetConnection, bool push = true) 
{ 
    string result = "Copy started"; 
    SqlConnection source = new SqlConnection(sourceConnection); 
    SqlConnection target = new SqlConnection(targetConnection); 
    SqlTransaction targetTransaction; 

    source.Open(); 
    target.Open(); 

    if (source.State != ConnectionState.Open || target.State != ConnectionState.Open) 
    { 
     throw new Exception("Unable to connect to server at this time."); 
    } 

    targetTransaction = target.BeginTransaction(); 

    try 
    { 
     ClearTable(target, targetTransaction, "TableAAA"); 
     ClearTable(target, targetTransaction, "TableBBB"); 

     CopyTable(source, target, targetTransaction, "TableAAA"); 
     CopyTable(source, target, targetTransaction, "TableBBB"); 

     targetTransaction.Commit(); 
     result = "Copy successful"; 
    } 
    catch (Exception E) 
    { 
     targetTransaction.Rollback(); 
     result = "An SQL Error has occurred. Unable to copy data at this time.\n\n" + E.Message;    
    } 
    finally 
    { 
     target.Close(); 
     source.Close(); 
    } 

    return result; 
} 

private static void ClearTable(SqlConnection destination, SqlTransaction tran, string table) 
{ 
    SqlCommand cmd = new SqlCommand(string.Format("DELETE FROM {0}", table), destination); 
    cmd.Transaction = tran; 
    cmd.ExecuteNonQuery(); 
} 

private static void CopyTable(SqlConnection source, SqlConnection destination, SqlTransaction tran, string table) 
{ 
    SqlCommand cmd = new SqlCommand(string.Format("DELETE FROM {0}", table), destination);    
    cmd.Transaction = tran; 
    cmd.ExecuteNonQuery(); 

    cmd = new SqlCommand(string.Format("SELECT * FROM {0}", table), source); 
    SqlDataReader reader = cmd.ExecuteReader(); 

    SqlBulkCopy bulkData = new SqlBulkCopy(destination, SqlBulkCopyOptions.Default, tran); 
    bulkData.DestinationTableName = table; 
    bulkData.BulkCopyTimeout = (int)Properties.Settings.Default.CommandTimeOut; 
    bulkData.WriteToServer(reader); 

    bulkData.Close(); 
    reader.Close(); 
} 

如果我強迫的錯誤,通過改變其中一個表的模式,當它試圖回滾任何更改時,我收到「This SqlTransaction has completed」錯誤。我如何糾正這個問題,爲什麼會發生?

回答

2

我不確定您遇到的具體問題,但我會建議您以使用using聲明的方式重寫您的代碼。這會阻止您明確關閉連接或回滾事務。

private static string CopyData(string sourceConnection, string targetConnection, bool push = true) 
{  
    using (var source = new SqlConnection(sourceConnection)) 
    using (var target = new SqlConnection(targetConnection)) 
    { 
     source.Open(); 
     target.Open(); 

     // no need to check for open status, as Open will throw an exception if it fails 

     using (var transaction = target.BeginTransaction()) 
     { 
      // do work 

      // no need to rollback if exception occurs 
      transaction.Commit(); 
     } 

     // no need to close connections explicitly 
    } 
} 
相關問題