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