2009-10-25 36 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