2009-10-25 37 views
5

我已經在我今天晚上知識刷牙,努力克服4年,因爲我的工作,爲公司的壞的編程習慣。我最近偶然發現的一件事是System.Transactions。在過去幾個小時閱讀了這些信息之後,我想我對自己的工作方式以及爲什麼要使用它們有充分的瞭解。但是,我所看到的所有示例都顯示了從事務內部調用的內聯T-SQL。做數據庫的訪問時,專門混合System.Transactions的與SqlTransactions

我幾乎使用存儲過程和現有的存儲過程都被包裹在自己SqlTransactions。你知道,使用'Begin Tran'然後回滾或提交。如果一個Stored Proc調用另一個存儲過程,它也會創建一個事務並且Commits冒泡,直到外層的提交或回退。很棒。

所以現在我的問題是,如果我想開始在我的代碼中使用System.Transactions - 爲了監視不能嵌套在單個存儲過程中的連續數據庫任務的簡單目的 - 這是如何與現有的SqlTransactions我已經在我的存儲特效?

在我的代碼中使用System.Transactions只會在實際提交之前添加一層保護,或者因爲我在SqlTransaction中顯式提交 - 數據是否會持久保留,而不管基於代碼提交還是回滾交易?

+0

在這個問題上接受的答案是錯誤的。在System.Transaction中使用Sql事務會導致意外的行爲(即Sql事務不參與外部System.Transaction!)這樣做會有效地中和您的事務。 – 2016-10-19 13:45:47

+0

感謝您跟進這些更正,比爾。 7年後,我甚至不記得是否我最終實施了任何需要這一點的事情,但最好有正確答案標記。 :) – WesleyJohnson 2016-10-20 16:04:29

回答

4

沒有,System.Transactions的和SQL事務不混合。

我引用以下MSDN文章「不要混合它們」:https://msdn.microsoft.com/en-us/library/ms973865.aspx

SQL事務不在外System.Transaction參加你所希望的方式。失敗或回滾的Sql事務不會導致System.Transaction內的其他活動回滾。


這個例子顯示了這種現象:

using (var tx = new TransactionScope()) 
{ 
    using (var con = new SqlConnection($"{connectionstring}")) 
    { 
     con.Open(); 

     using (var com = new SqlCommand($"set xact_abort on; begin transaction; INSERT INTO dbo.KeyValueTable VALUES ('value1', '{Guid.NewGuid()}'); rollback;", con)) 
     { 
      // This transaction failed, but it doesn't rollback the entire system.transaction! 
      com.ExecuteNonQuery(); 
     } 

     using (var com = new SqlCommand($"set xact_abort on; begin transaction; INSERT INTO dbo.KeyValueTable VALUES ('value2', '{Guid.NewGuid()}'); commit;", con)) 
     { 
      // This transaction will actually persist! 
      com.ExecuteNonQuery(); 
     } 
    } 
    tx.Complete(); 
} 

運行在一個空的數據存儲這個例子中,你應該注意到,從第二個SQL操作的記錄確實承諾之後,當C#的結構代碼將暗示他們不應該。


簡而言之,你不應該混合它們。如果您正在應用程序中編排多個Sql事務,則應該只使用System.Transactions。不幸的是,這意味着從您的所有存儲過程中刪除您的交易代碼,但是,唉,這是必要的,因爲對於混合模型,您無法保證數據的完整性。

+0

謝謝你,我改變了接受的答案。 – WesleyJohnson 2016-10-20 16:04:49

+0

如果將一個明確的ADO.Net事務用於SqlCommand並且該事務已加入到XA事務中(或甚至可能),該怎麼辦?這會取消XA交易嗎? – STLDeveloper 2018-02-02 18:59:51

-1

工作得很好,如果存儲的特效中你內心的事務被提交一切都會犯。如果其中一個回滾,那麼外部通道內的所有內容都將回滾。純淨的魔力。 :)

+0

優秀。這就是我所希望的,這似乎是合乎邏輯的答案,我只是不想假設。非常感激。 – WesleyJohnson 2009-10-25 08:43:26

+0

這是完全錯誤的。請參閱:https://msdn.microsoft.com/en-us/library/ms973865.aspx – 2016-10-19 13:43:12

+0

接受的答案已更改。 :) – WesleyJohnson 2016-10-20 16:05:01