Skip to content

Commit 66ed2c7

Browse files
authored
Merge pull request #623 from bgrainger/enlist-transaction
Rewrite EnlistTransaction to keep a list of open sessions.
2 parents 76877f4 + 11d0171 commit 66ed2c7

File tree

6 files changed

+406
-147
lines changed

6 files changed

+406
-147
lines changed

src/MySqlConnector/Core/ImplicitTransactionBase.cs renamed to src/MySqlConnector/Core/EnlistedTransactionBase.cs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,18 @@
55

66
namespace MySqlConnector.Core
77
{
8-
internal abstract class ImplicitTransactionBase : IEnlistmentNotification
8+
internal abstract class EnlistedTransactionBase : IEnlistmentNotification
99
{
10-
public MySqlConnection Connection { get; }
10+
// A MySqlConnection that holds the ServerSession that was enrolled in the transaction
11+
public MySqlConnection Connection { get; set; }
12+
13+
// Whether the connection is idle, i.e., a client has closed it and is no longer using it
14+
public bool IsIdle { get; set; }
1115

1216
public Transaction Transaction { get; private set; }
1317

14-
public void Start(Transaction transaction)
18+
public void Start()
1519
{
16-
Transaction = transaction;
1720
OnStart();
1821
Transaction.EnlistVolatile(this, EnlistmentOptions.None);
1922
}
@@ -28,21 +31,25 @@ void IEnlistmentNotification.Commit(Enlistment enlistment)
2831
{
2932
OnCommit(enlistment);
3033
enlistment.Done();
31-
Connection.UnenlistTransaction(this, Transaction);
34+
Connection.UnenlistTransaction();
3235
Transaction = null;
3336
}
3437

3538
void IEnlistmentNotification.Rollback(Enlistment enlistment)
3639
{
3740
OnRollback(enlistment);
3841
enlistment.Done();
39-
Connection.UnenlistTransaction(this, Transaction);
42+
Connection.UnenlistTransaction();
4043
Transaction = null;
4144
}
4245

4346
public void InDoubt(Enlistment enlistment) => throw new NotImplementedException();
4447

45-
protected ImplicitTransactionBase(MySqlConnection connection) => Connection = connection;
48+
protected EnlistedTransactionBase(Transaction transaction, MySqlConnection connection)
49+
{
50+
Transaction = transaction;
51+
Connection = connection;
52+
}
4653

4754
protected abstract void OnStart();
4855
protected abstract void OnPrepare(PreparingEnlistment enlistment);
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#if !NETSTANDARD1_3
2+
using System;
3+
using System.Transactions;
4+
using MySql.Data.MySqlClient;
5+
using MySqlConnector.Utilities;
6+
7+
namespace MySqlConnector.Core
8+
{
9+
internal sealed class StandardEnlistedTransaction : EnlistedTransactionBase
10+
{
11+
public StandardEnlistedTransaction(Transaction transaction, MySqlConnection connection)
12+
: base(transaction, connection)
13+
{
14+
}
15+
16+
protected override void OnStart()
17+
{
18+
string isolationLevel;
19+
switch (Transaction.IsolationLevel)
20+
{
21+
case IsolationLevel.Serializable:
22+
isolationLevel = "serializable";
23+
break;
24+
case IsolationLevel.ReadCommitted:
25+
isolationLevel = "read committed";
26+
break;
27+
case IsolationLevel.ReadUncommitted:
28+
isolationLevel = "read uncommitted";
29+
break;
30+
case IsolationLevel.Snapshot:
31+
case IsolationLevel.Chaos:
32+
throw new NotSupportedException("IsolationLevel.{0} is not supported.".FormatInvariant(Transaction.IsolationLevel));
33+
// "In terms of the SQL:1992 transaction isolation levels, the default InnoDB level is REPEATABLE READ." - http://dev.mysql.com/doc/refman/5.7/en/innodb-transaction-model.html
34+
case IsolationLevel.Unspecified:
35+
case IsolationLevel.RepeatableRead:
36+
default:
37+
isolationLevel = "repeatable read";
38+
break;
39+
}
40+
41+
using (var cmd = new MySqlCommand("set transaction isolation level " + isolationLevel + "; start transaction;", Connection))
42+
cmd.ExecuteNonQuery();
43+
}
44+
45+
protected override void OnPrepare(PreparingEnlistment enlistment)
46+
{
47+
}
48+
49+
protected override void OnCommit(Enlistment enlistment)
50+
{
51+
using (var cmd = new MySqlCommand("commit;", Connection))
52+
cmd.ExecuteNonQuery();
53+
}
54+
55+
protected override void OnRollback(Enlistment enlistment)
56+
{
57+
using (var cmd = new MySqlCommand("rollback;", Connection))
58+
cmd.ExecuteNonQuery();
59+
}
60+
}
61+
}
62+
#endif

src/MySqlConnector/Core/StandardImplicitTransaction.cs

Lines changed: 0 additions & 63 deletions
This file was deleted.

src/MySqlConnector/Core/XaImplicitTransaction.cs renamed to src/MySqlConnector/Core/XaEnlistedTransaction.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66

77
namespace MySqlConnector.Core
88
{
9-
internal sealed class XaImplicitTransaction : ImplicitTransactionBase
9+
internal sealed class XaEnlistedTransaction : EnlistedTransactionBase
1010
{
11-
public XaImplicitTransaction(MySqlConnection connection)
12-
: base(connection)
11+
public XaEnlistedTransaction(Transaction transaction, MySqlConnection connection)
12+
: base(transaction, connection)
1313
{
1414
}
1515

0 commit comments

Comments
 (0)