c# - 无法将 TransactionScope 与任务一起使用

标签 c# task-parallel-library task transactionscope

我正尝试在对不同 SQL Server 实例的两个查询中使用 TransactionScope(事务被提升为 MSDTC)。我让它在不使用 Tasks 的情况下同步工作,但在异步使用 Tasks 时无法使事务回滚。

我已经隐藏了服务器的连接字符串和更新语句,但请放心,它们都可以毫无问题地连接和执行 SQL。我有意将方法 runTwo() 中的 SQL 设置为失败并引发异常。

我正在使用 .Net 4.5.2,其中包括枚举 TransactionScopeAsyncFlowOption.Enabled(在 TransactionScope 构造函数中),我认为它应该处理跨线程的事务,但我无法让它工作。

static void Main()
        {
            List<Task> tasks = new List<Task>();
            using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                try
                {
                    tasks.Add(Task.Run(() => runOne()));
                    tasks.Add(Task.Run(() => runTwo()));

                    Task.WhenAll(tasks);

                    //Complete the scope
                    scope.Complete();
                }
                catch (Exception)
                {
                    Transaction.Current.Rollback();
                }
            }
            Console.ReadLine();
        }

        private static void runOne()
        {
            //Get the base SQL connection
            using (SqlConnection conn = new SqlConnection("Data Source=SERVER1....."))
            {
                conn.Open();

                SqlCommand command1 = new SqlCommand
                {
                    CommandText = "Update .. Complete Successfully",
                    CommandType = CommandType.Text,
                    Connection = conn
                };

                command1.ExecuteNonQuery();
            }
        }

        private static void runTwo()
        {
            using (
                SqlConnection conn =
                    new SqlConnection("Data Source=SERVER2...")
                )
            {
                conn.Open();

                SqlCommand command2 = new SqlCommand
                {
                    CommandText = "Update .... Raises Exception",
                    CommandType = CommandType.Text,
                    Connection = conn
                };

                //Execute the command
                command2.ExecuteNonQuery();

            }
        }

最佳答案

这个:

Task.WhenAll(tasks);

是你的问题。 Task.WhenAll 返回一个 awaitable,它不会阻塞 方法调用。由于您使用的是无法等待的控制台应用程序,因此您必须推迟使用 Task.WaitAll 而不是它会显式阻塞,直到两个请求都完成并通过 AggregateException 传播任何异常

try
{
    Task.WaitAll(new[] { Task.Run(() => runOne()), 
                         Task.Run(() => runTwo()) });
    scope.Complete();
}

关于c# - 无法将 TransactionScope 与任务一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28065644/

相关文章:

linux - 内核在哪里存储未运行的进程?

c# - 使用 Task[] 对象引用时未设置为对象的实例

c# - 重新启动已完成的任务

c# - 如何将 EF 核心迁移添加到 .net 核心 2 类库?

c# - 查找一个字节数组是否包含另一个字节数组的最快方法是什么?

c# - 无限期地在任务上调用 .ContinueWith 是模拟队列和循环线程的有效方法吗?

c# - TPL 数据流 block 下游如何获取源生成的数据?

c# - Task.Faulted 和 Task.Exception

c# - iMacros (Firefox) 通过 C# 控制

c# - 在特定时间间隔后调用函数