Bug #113585 并发多个连接时报错 System.NotSupportedException: MySQL Connector/NET does not currently s
Submitted: 9 Jan 2024 1:41 Modified: 9 Jan 2024 7:24
Reporter: ada jin Email Updates:
Status: Verified Impact on me:
None 
Category:Connector / NET Severity:S3 (Non-critical)
Version:8.2.0 OS:Any
Assigned to: CPU Architecture:Any

[9 Jan 2024 1:41] ada jin
Description:
if (driver.currentTransaction == null)
{
  MySqlPromotableTransaction t = new MySqlPromotableTransaction(this, transaction);
  if (!transaction.EnlistPromotableSinglePhase(t))
    Throw(new NotSupportedException(Resources.DistributedTxnNotSupported));

  driver.currentTransaction = t;
  DriverTransactionManager.SetDriverInTransaction(driver);
  driver.IsInActiveUse = true;
}
多个连接一起并发await时会报错System.NotSupportedException: MySQL Connector/NET does not currently support distributed transactions.

How to repeat:
using Dapper;
using System.Diagnostics;
using System.Transactions;

namespace ConsoleApp1
{
    internal class Program
    {
        static async Task Main(string[] args)
        {
            try
            {
                Stopwatch stopwatch = Stopwatch.StartNew();
                var performanceTesting = new PerformanceTesting();
                //await performanceTesting.TestPagedAsync();
                //for (int i = 0; i < 10; i++)
                //{

                using (TransactionScope ts = new(TransactionScopeOption.Required,
                    new TransactionOptions
                    {
                        IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted,
                        Timeout = TimeSpan.FromSeconds(10)
                    }, TransactionScopeAsyncFlowOption.Enabled))
                {
                    var task1 =    performanceTesting.Test1Async();
                    var task2 =  performanceTesting.Test2Async();
                    await Task.WhenAll(task1, task2);
                    //await performanceTesting.TestUserAsync();
                    ts.Complete();
                }
                //}
                Console.WriteLine(stopwatch.Elapsed.ToString());
            }
            catch (Exception ex)
            {

                Console.WriteLine(ex.ToString());
            }
        }

        

    }
    
    class PerformanceTesting
    {
       const string connectionString = "Data Source=10.10.79.16;port=3371;User ID=afdsfsaf;Password=fgadfasd;Database=test;CharSet=utf8;sslmode=none;maxpoolsize=1000;minpoolsize=5;";
        const string userConnectionString = "Data Source=10.10.79.16;port=3371;User ID=dasfasdf;Password=sdfas;Database=test;CharSet=utf8;sslmode=none;maxpoolsize=1000;minpoolsize=5;";
 
        public void Test1()
        {
            using var conn = new MySql.Data.MySqlClient.MySqlConnection(connectionString);
            conn.Open();
            using var command = conn.CreateCommand();
            command.CommandText = $"INSERT INTO `test`.`test1`(`Name`) VALUES ('{Random.Shared.Next(10000)}');";
            command.ExecuteNonQuery();
        }
        public async Task<int> Test1Async()
        {
            using var conn = new MySql.Data.MySqlClient.MySqlConnection(connectionString);
            if (conn.State == System.Data.ConnectionState.Closed)
                await conn.OpenAsync();
            Console.WriteLine($"conn.ServerThread:{conn.ServerThread},ManagedThreadId:{Thread.CurrentThread.ManagedThreadId},GetHashCode:{conn.GetHashCode()}");
            using var command = conn.CreateCommand();
            command.CommandText = $"INSERT INTO `test`.`test1`(`Name`) VALUES ('{Random.Shared.Next(10000)}');";
            return await command.ExecuteNonQueryAsync();
        }
        
        public void Test2()
        {
            using var conn = new MySql.Data.MySqlClient.MySqlConnection(connectionString);
            conn.Open();
            using var command = conn.CreateCommand();
            command.CommandText = $"INSERT INTO `test`.`test2`(`Name`) VALUES ('{Random.Shared.Next(10000)}');";
            command.ExecuteNonQuery();
        }
        public async Task<int> Test2Async()
        {
            using var conn = new MySql.Data.MySqlClient.MySqlConnection(connectionString);
            if (conn.State == System.Data.ConnectionState.Closed)
                await conn.OpenAsync();
            Console.WriteLine($"conn.ServerThread:{conn.ServerThread},ManagedThreadId:{Thread.CurrentThread.ManagedThreadId},GetHashCode:{conn.GetHashCode()}");

            using var command = conn.CreateCommand();
            command.CommandText = $"INSERT INTO `test`.`test2`(`Name`) VALUES ('{Random.Shared.Next(10000)}');";
            return await command.ExecuteNonQueryAsync();
        }
        public void TestUser()
        {
            using var conn = new MySql.Data.MySqlClient.MySqlConnection(userConnectionString);
            conn.Open();
            using var command = conn.CreateCommand();
            command.CommandText = $"INSERT INTO `test2`(`Name`) VALUES ('{Random.Shared.Next(10000)}');";
            command.ExecuteNonQuery();
        }

        public async Task<int> TestUserAsync()
        {
            using var conn = new MySql.Data.MySqlClient.MySqlConnection(userConnectionString);
            if (conn.State == System.Data.ConnectionState.Closed)
                await conn.OpenAsync();
            using var command = conn.CreateCommand();
            command.CommandText = $"INSERT INTO `test2`(`Name`) VALUES ('{Random.Shared.Next(10000)}');";
            return await command.ExecuteNonQueryAsync();
        }

        public async Task<int> TestPagedAsync()
        {
            using var conn = new MySql.Data.MySqlClient.MySqlConnection(userConnectionString);
            var testObjTask = conn.QueryFirstAsync<TestObj>("SELECT * FROM `test2`");
           
            var countTask = conn.ExecuteScalarAsync<int>("SELECT COUNT(*) FROM `test2`");
            var testObj = await testObjTask;
            var count = await countTask;
            Console.WriteLine(testObj.ToString());
            return count;
        }
        record TestObj { 
        public int Id { get; set; }
            public string Name { get; set; } = string.Empty;
        }
    }

}
[9 Jan 2024 7:24] MySQL Verification Team
Hello Ada jin,

Thank you for the report and feedback.

regards,
Umesh