2011-09-28 47 views
2

我有一個SQL Server存儲過程創建一個像這樣的交易:交易在存儲過程+客戶端代碼

BEGIN TRY 
    BEGIN TRANSACTION 

    INSERT INTO Table1 ... 
    INSERT INTO Table2 ... 

    COMMIT 
END TRY 
BEGIN CATCH 
    IF @@TRANCOUNT > 0 
     ROLLBACK 
END CATCH 

此存儲過程將插入到兩個獨立的表。如果其中一個失敗,它會回滾。

我也有一個創建事務範圍下面的.NET代碼:如果兩個我的存儲過程

using(var scope = new TransactionScope()) 
{ 
    SqlCommand cmd1 = connection.CreateCommand(); 
    SqlCommand cmd2 = connection.CreateCommand(); 

    // ... 

    cmd1.ExecuteNonQuery(); 
    cmd2.ExecuteNonQuery(); 

    scope.Complete(); 
} 

會發生什麼事,我的代碼創建一個交易?這是否會導致問題/需要成爲分佈式事務,或者只要我只創建一個到數據庫的連接就可以了?

回答

0

在這種情況下,如果其中一個存儲過程失敗,它將使用內部事務進行回滾。您的代碼會認爲它已完成並提交分佈式事務。這是你想要的,因爲每個人都可以單獨運行,因此分解交易是毫無意義的。

如果您希望既運行又不運行,則從存儲的程序中刪除您的事務,並使用分佈式事務。

+0

存儲過程會將錯誤冒泡起來,而不是吞下它。我的例子並沒有表現出這種抱歉。 – Dismissile

+0

@Dismissile - 您發現錯誤並回滾事務。在你的'CATCH'內沒有錯誤 – cjk

+0

我的意思是我的例子沒有顯示我的RAISERROR,儘管我的真實情況是這樣做的。 – Dismissile

3

除非您有充分的理由,否則我只會在一個地方或另一個地方進行交易。

如果可能的話,我會讓那個地方成爲數據庫。這樣可以減少往返次數,更容易測試,將其與系統的其他組件隔離開來,減少暴露的數據庫表面面積,並通過強制操作通過定義良好的界面來保護數據庫的周邊完整性。