Skip to content

Commit f6a6b61

Browse files
committed
Respect System.Transactions IsolationLevel. Fixes #605
1 parent 2ede020 commit f6a6b61

File tree

2 files changed

+81
-1
lines changed

2 files changed

+81
-1
lines changed

src/MySqlConnector/Core/StandardImplicitTransaction.cs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,33 @@ public StandardImplicitTransaction(MySqlConnection connection) : base(connection
1212

1313
protected override void OnStart()
1414
{
15-
m_transaction = Connection.BeginTransaction();
15+
System.Data.IsolationLevel isolationLevel;
16+
switch (Transaction.IsolationLevel)
17+
{
18+
case IsolationLevel.Serializable:
19+
isolationLevel = System.Data.IsolationLevel.Serializable;
20+
break;
21+
case IsolationLevel.RepeatableRead:
22+
isolationLevel = System.Data.IsolationLevel.RepeatableRead;
23+
break;
24+
case IsolationLevel.ReadCommitted:
25+
isolationLevel = System.Data.IsolationLevel.ReadCommitted;
26+
break;
27+
case IsolationLevel.ReadUncommitted:
28+
isolationLevel = System.Data.IsolationLevel.ReadUncommitted;
29+
break;
30+
case IsolationLevel.Snapshot:
31+
isolationLevel = System.Data.IsolationLevel.Snapshot;
32+
break;
33+
case IsolationLevel.Chaos:
34+
isolationLevel = System.Data.IsolationLevel.Chaos;
35+
break;
36+
case IsolationLevel.Unspecified:
37+
default:
38+
isolationLevel = System.Data.IsolationLevel.Unspecified;
39+
break;
40+
}
41+
m_transaction = Connection.BeginTransaction(isolationLevel);
1642
}
1743

1844
protected override void OnPrepare(PreparingEnlistment enlistment)

tests/SideBySide/TransactionScopeTests.cs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4+
using System.Threading.Tasks;
45
using System.Transactions;
56
using Dapper;
67
using MySql.Data.MySqlClient;
@@ -533,6 +534,58 @@ public void TwoSimultaneousConnectionsThrowsWithNonXaTransactions()
533534
}
534535
}
535536

537+
[Fact]
538+
public void SimultaneousConnectionsWithTransactionScopeReadCommittedWithNonXaTransactions()
539+
{
540+
var connectionString = AppConfig.ConnectionString;
541+
#if !BASELINE
542+
connectionString += ";UseXaTransactions=False";
543+
#endif
544+
545+
// from https://github.com/mysql-net/MySqlConnector/issues/605
546+
using (var connection = new MySqlConnection(connectionString))
547+
{
548+
connection.Open();
549+
connection.Execute(@"DROP TABLE IF EXISTS orders;
550+
CREATE TABLE `orders`(
551+
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
552+
`description` VARCHAR(50),
553+
PRIMARY KEY (`id`)
554+
);");
555+
}
556+
557+
var task = Task.Run(() => UseTransaction());
558+
UseTransaction();
559+
task.Wait();
560+
561+
void UseTransaction()
562+
{
563+
// This TransactionScope may be overly configured, but let's stick with the one I am actually using
564+
using (var transactionScope = new TransactionScope(TransactionScopeOption.Required,
565+
new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted },
566+
TransactionScopeAsyncFlowOption.Enabled))
567+
{
568+
using (var connection = new MySqlConnection(connectionString))
569+
using (var command = connection.CreateCommand())
570+
{
571+
command.CommandText = @"SELECT MAX(id) FROM orders FOR UPDATE;";
572+
connection.Open();
573+
command.ExecuteScalar();
574+
}
575+
576+
using (var connection = new MySqlConnection(connectionString))
577+
using (var command = connection.CreateCommand())
578+
{
579+
command.CommandText = @"INSERT INTO orders (description) VALUES ('blabla'), ('blablabla');";
580+
connection.Open();
581+
command.ExecuteNonQuery();
582+
}
583+
584+
transactionScope.Complete();
585+
}
586+
}
587+
}
588+
536589
[Fact]
537590
public void TwoDifferentConnectionStringsThrowsWithNonXaTransactions()
538591
{
@@ -594,3 +647,4 @@ public void CannotMixNonXaAndXaTransactions()
594647
DatabaseFixture m_database;
595648
}
596649
}
650+

0 commit comments

Comments
 (0)