2015-06-11 96 views
0

當我更新某事到MS SQL 2005數據庫與C#,我想使用嵌套的SQL事務。我試了下面的代碼:c#與sql嵌套事務

try 
{ 
    conn.Open(); 
    cmd.Connection = conn; 
    cmd.Transaction = conn.BeginTransaction(); 

    ////BEGIN TRAN 
    cmd.CommandType = CommandType.StoredProcedure; 
    cmd.CommandText = "storeprocname"; 
    cmd.Parameters.Add("@xxx", SqlDbType.VarChar, 50); 
    cmd.Parameters["@xxx"].Value = "string_value"; 
    cmd.ExecuteNonQuery(); 
    if (<sql can do>) 
    { 
     cmd.Transaction.Commit(); 
    } 
    else 
    { 
     cmd.Transaction.Rollback(); 
    } 
} 
catch (Exception ex) 
{ 
    cmd.Transaction.Rollback(); 
} 

上面的代碼打開一個事務,並把一些數據在sql中。如果我提供的數據是正確的,它可以運行。但是,如果它不是,它逮住了以下錯誤,比我預想的完全不同,這就是:

[System.Data.SqlClient.SqlException] = {「不能回退updatetransport沒有事務或保存。 。的該名稱被發現\ r \ nTransaction計數後EXECUTE表示COMMIT或回滾事務語句丟失一個計數= 1,當前計數= 2「}

和代碼是SQL:

begin tran updatetransport 
update db set [email protected] where [email protected] 
if @@rowcount < 1 or @@error <> 0 -- no record updated 
begin 
    rollback tran updatetransport /*updatran is the name of transaction*/ 
return -1 --fail 
    end 
    else 
begin 
commit tran updatetransport 
return 0 --success 
end 

看來,sq l服務器會自動回滾事務。當我試圖回滾它時拋出錯誤。但是,當我試圖按照以下方式修改代碼時,仍然沒有運氣。我錯過了什麼嗎? 剛開始交易後,我已聲明@tcount [email protected]@TRANCOUNT

if @tcount = @@TRANCOUNT 
begin 
    rollback tran updatetransport 
end 
+5

避免嵌套事務。因爲他們不是。我已經編寫了很長一段時間,從不需要代碼中的嵌套事務。你認爲你需要的事實表明你的設計可能是錯誤的。 –

+0

你的存儲過程中已經有了一個事務,你不需要另外一個在c#代碼中。 –

+1

我知道這是多餘的,但有時候可能會有兩個人處理sql和c#。當某些想法在邏輯上起作用時,這也令人沮喪,但這種情況並不像預期的那樣發生。對或錯必須記錄在案。 – martin

回答

0

如果已經存在外,您不應該開始嵌套事務,這個你可以檢查在@@ trancount變量開始過程,並在結尾:

declare @trancount int = @@trancount 

if @trancount = 0 
    begin tran updatetransport 

update db set [email protected] where [email protected] 
if @@rowcount < 1 or @@error <> 0 -- no record updated 
begin 
    if @trancount = 0 
     rollback tran updatetransport /*updatran is the name of transaction*/ 
return -1 --fail 
    end 
    else 
begin 
    if @trancount = 0 
    commit tran updatetransport 
return 0 --success 
end 
0

的SQL Server並沒有真正嵌套交易 - 或者至少以開發人員所承擔的方式。你可以開始嵌套事務,但它們並沒有任何影響,因爲提交最內層的事務在現實中並沒有做任何事情。

根本無法回滾最內層的事務,因爲無法將名稱與回滾一起使用,並且沒有該名稱的回滾對最外層的事務執行回滾。

您可以通過Paul Randal