C# 混合System.Transactions和SqlTransactions

C# 混合System.Transactions和SqlTransactions,c#,asp.net,sql-server,ado.net,C#,Asp.net,Sql Server,Ado.net,今天晚上,我一直在温习我的知识,试图克服4年来由于我所在的公司而造成的糟糕编程实践。我最近偶然发现的一件事是System.Transactions。在阅读了过去几个小时关于它们的内容后,我认为我已经充分了解了它们的工作原理以及您为什么要使用它们。然而,我看到的所有示例都显示了从事务中调用内联T-SQL 在进行数据库访问时,我几乎完全使用存储过程,现有的存储过程都封装在它们自己的SqlTransactions中。你知道,使用“Begin Tran”然后回滚或提交。如果一个存储的进程调用另一个存储的

今天晚上,我一直在温习我的知识,试图克服4年来由于我所在的公司而造成的糟糕编程实践。我最近偶然发现的一件事是System.Transactions。在阅读了过去几个小时关于它们的内容后,我认为我已经充分了解了它们的工作原理以及您为什么要使用它们。然而,我看到的所有示例都显示了从事务中调用内联T-SQL

在进行数据库访问时,我几乎完全使用存储过程,现有的存储过程都封装在它们自己的SqlTransactions中。你知道,使用“Begin Tran”然后回滚或提交。如果一个存储的进程调用另一个存储的进程,它也会创建一个事务,提交冒泡,直到外部进程提交或回滚。效果很好

所以现在我的问题是,如果我想在代码中开始使用System.Transactions(为了监视不能嵌套在单个存储过程中的连续数据库任务),那么它如何处理存储过程中已有的现有SqlTransactions


在我的代码中使用System.Transactions会在实际提交之前再添加一层保护吗?或者因为我在SqlTransaction中显式提交数据,所以无论在基于代码的事务中提交还是回滚,数据都会被持久化吗,如果已提交存储过程中的内部事务,则所有事务都将提交。如果其中一个回滚,那么外部事务中的所有内容都将回滚。纯魔法。:)

否,系统事务和Sql事务不混合。

我引用以下MSDN文章中的“不要混合它们”:

Sql事务不参与外部系统。请按照您希望的方式进行事务处理。失败或回滚的Sql事务不会导致系统内的其他活动。事务回滚


此示例显示了以下现象:

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。不幸的是,这将意味着从所有存储过程中删除事务代码,但遗憾的是,这是必要的,因为对于混合模型,您无法保证数据的完整性。

非常好。这就是我所希望的,这似乎是合乎逻辑的答案,我只是不想假设。非常感谢。这绝对是错误的。请参阅:已接受的答案已更改。:)这个问题的公认答案是错误的。在系统内使用Sql事务。事务会导致意外行为(即,Sql事务不参与外部系统。事务!)这样做会有效地使您的事务无效。感谢您继续进行更正,Bill。7年后,我甚至记不起我是否最终实现了任何需要这个的东西,但最好能标记出正确的答案。:)如果SqlCommand使用了显式ADO.Net事务,并且该事务被登记到XA事务中(或者这是可能的),该怎么办?这会取消XA事务吗?