Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Distributed Transactions: .NET Framework vs .NET Core

I have the following code sample:

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();
​
}

When executing this code in a .NET Framework (4.8) Console Application (against SQL Server Express 2017) it yields the following output:

Output of code in .NET Framework Console

Since the transaction is being promoted to a Distributed Transaction, I expect a similar Console Application targeting .NET Core (3.0) to throw a

System.PlatformNotSupportedException (This platform does not support distributed transactions.).

However, the actual output is:

Output of code in .NET Core Console

Why is this? I expect the promotion of a transaction to a distributed transaction to be framework-agnostic.


Edit: This .NET Core (3.0) code sample does something with the database connections:

Database Schema:

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

.NET Core (3.0) Console Application:

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();
}

And the Console output:

.NET Core Console output when doing something with the connections

Note: This sample also succeeds when using 2 different connectionstrings for the 2 connections!

like image 874
chrisv Avatar asked Dec 02 '19 08:12

chrisv


1 Answers

NET Core doesn't support Distributed Transactions because it would require a different transaction manager on each platform. You can find more about this issue on https://github.com/dotnet/runtime/issues/715.

This feature seems to be added to Release 5.0 from .NET Due by November 30, 2020

There is another thread SA talking about this problem.

like image 62
mohamed talaat Avatar answered Oct 26 '22 02:10

mohamed talaat