【问题标题】:Distributed Transactions: .NET Framework vs .NET Core分布式事务:.NET Framework 与 .NET Core
【发布时间】:2020-03-26 20:37:20
【问题描述】:

我有以下代码示例:

static void Main(string[] args)
{
    TransactionManager.DistributedTransactionStarted += (sender, eventArgs) =>
    {
        Console.WriteLine("Promoted to distributed transaction!");
    };
​
    const string connectionString = @"Server=localhost\SQLEXPRESS;Database=master;Integrated Security=true;";
​
    using (var tx = new TransactionScope())
    using (var conn1 = new SqlConnection(connectionString))
    using (var conn2 = new SqlConnection(connectionString))
    {
        conn1.Open();
        Console.WriteLine("conn1 opened");
​
        conn2.Open();
        Console.WriteLine("conn2 opened");
​
        tx.Complete();
    }
​
    Console.ReadLine();
​
}

在 .NET Framework (4.8) 控制台应用程序(针对 SQL Server Express 2017)中执行此代码时,会产生以下输出:

由于事务被提升为分布式事务,我希望类似的面向 .NET Core (3.0) 的控制台应用程序会抛出一个

System.PlatformNotSupportedException(此平台不支持分布式事务。)。

然而,实际的输出是:

这是为什么?我希望将事务提升为分布式事务与框架无关。


编辑: 这个 .NET Core (3.0) 代码示例对数据库连接做了一些事情:

数据库架构:

CREATE DATABASE [TestDB1] 
GO
CREATE TABLE [TestDB1].[dbo].[Table]([Value] [nvarchar](max) NULL) 

.NET Core (3.0) 控制台应用程序:

static void Main(string[] args)
{
    TransactionManager.DistributedTransactionStarted += (sender, eventArgs) =>
    {
        Console.WriteLine("Promoted to distributed transaction!");
    };

    const string connectionString = @"Server=localhost\SQLEXPRESS;Database=TestDB1;Integrated Security=true;";

    using (var tx = new TransactionScope())
    using (var conn1 = new SqlConnection(connectionString))
    using (var conn2 = new SqlConnection(connectionString))
    {
        conn1.Open();
        Console.WriteLine("conn1 opened");
        using (var cmd1 = conn1.CreateCommand())
        {
            cmd1.CommandText = "INSERT INTO [dbo].[Table] ([Value]) VALUES ('test 1')";
            cmd1.ExecuteNonQuery();
            Console.WriteLine("Record inserted through conn1");
        }

        conn2.Open();
        Console.WriteLine("conn2 opened");
        using (var cmd2 = conn2.CreateCommand())
        {
            cmd2.CommandText = "INSERT INTO [dbo].[Table] ([Value]) VALUES ('test 1')";
            cmd2.ExecuteNonQuery();
            Console.WriteLine("Record inserted through conn2");
        }

        tx.Complete();
        Console.WriteLine("Transaction completed");
    }

    Console.ReadLine();
}

还有控制台输出:

注意:此示例在为 2 个连接使用 2 个不同 连接字符串时也成功!

【问题讨论】:

  • 尝试从连接中实际做一些事情。
  • 我无法重现这一点——不在 .NET Core 3 上,不在 3.1 上,在 System.Data.SqlClient 上,在 Microsoft.Data.SqlClient 上都没有。所有变体都会产生异常。
  • transactionscope 在 .Net Core 2.0 中引入 是否涵盖了您的用例?看看它的example

标签: c# .net sql-server .net-core msdtc


【解决方案1】:

NET Core支持分布式事务,因为它需要在每个平台上使用不同的事务管理器。 您可以在 https://github.com/dotnet/runtime/issues/715 上找到有关此问题的更多信息。

此功能似乎已添加到 .NET 的 5.0 版中,截止日期为 2020 年 11 月 30 日

还有另一个线程SA在谈论这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-15
    • 2012-09-03
    • 2018-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-25
    • 1970-01-01
    相关资源
    最近更新 更多