2016-04-28 41 views
0

我有2個查詢必須一起工作。首先是更新,第二個是插入查詢。我把它們變成TransactionScope的範圍:TransactionScope不回滾查詢

using (TransactionScope scope = new TransactionScope()) 
{ 
    SqlCommand updateCmd = new SqlCommand("UPDATE V_Stock SET Quantity= 5 WHERE Id=" + shelfId, con); 
    SqlCommand insertCmd = new SqlCommand("INSERT INTO V_Stock (Code, Quantity, Name) VALUES (@1, @2, @3)", con); 
    insertCmd.Parameters.AddWithValue("@1", "Code1"); 
    insertCmd.Parameters.AddWithValue("@2", 15); 
    insertCmd.Parameters.AddWithValue("@3", "Name1"); 
    try 
    { 
     updateCmd.ExecuteNonQuery(); 
     insertCmd.ExecuteNonQuery();    
    } 
    catch (Exception ex) 
    { 
     scope.Complete(); 
     string s = ex.ToString(); 
    } 
} 

更新查詢工作正常但插入查詢沒有。在這種情況下,我不想執行它們。只有他們正常工作時才應該執行它們。

我能做些什麼來一起工作這些查詢?

+2

滴'scope.Dispose()'線,採用(會爲你做到這一點。也爲什麼你需要在變量中捕獲?也許缺少記錄? – sll

+1

調用'scope.Dispose()'是不必要的,'using'已經做到了。但是,在查詢完成後,您確實需要顯式調用scope.Complete(),否則scope *將會回滾。而且,目前還不清楚你的意思是「不回滾」和「一起工作」。你想要達到什麼目標以及實際發生了什麼? –

+2

另外,在調用ExecuteNonQuery之後,您需要調用scope.Complete()來提交事務。 –

回答

2
  • 當您準備好提交事務時,而不是在失敗時,您需要調用scope.Complete
  • 您還應該打開TransactionScope範圍內的連接,以便將連接註冊到該範圍。
  • 另外我不確定你的SqlConnection實例是在哪裏定義的。微軟團隊總是建議你使用短暫的連接,使用它們並擺脫它們。讓Sql服務器處理連接池(通常這是默認情況下),這使得它非常便宜,並在您的C#代碼中丟棄sql連接。

下面是一些重構的代碼,我加的)一些文件,我在微軟的定義發現TransactionScope

using (TransactionScope scope = new TransactionScope()) 
{ 
    using (SqlConnection con = new SqlConnection(yourConnectString)) 
    { 
     // according to the documentation on TransactionScope 
     // Opening the connection automatically enlists it in the 
     // TransactionScope as a lightweight transaction. 
     con.Open(); 

     // I changed this to make it parameterized as well although this had nothing to do with the TransactionScope question 
     SqlCommand updateCmd = new SqlCommand("UPDATE V_Stock SET Quantity= 5 WHERE Id= @shelfId", con); 
     updateCmd.Parameters.AddWithValue("@shelfId", shelfId); 

     SqlCommand insertCmd = new SqlCommand("INSERT INTO V_Stock (Code, Quantity, Name) VALUES (@1, @2, @3)", con); 
     insertCmd.Parameters.AddWithValue("@1", "Code1"); 
     insertCmd.Parameters.AddWithValue("@2", 15); 
     insertCmd.Parameters.AddWithValue("@3", "Name1"); 

     updateCmd.ExecuteNonQuery(); 
     insertCmd.ExecuteNonQuery();    

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