Skip to content

Commit 2f0183a

Browse files
committed
Rewrite EnlistTransaction to keep a list of open sessions.
Signed-off-by: Bradley Grainger <[email protected]>
1 parent 76877f4 commit 2f0183a

File tree

5 files changed

+355
-96
lines changed

5 files changed

+355
-96
lines changed

src/MySqlConnector/Core/ImplicitTransactionBase.cs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@ namespace MySqlConnector.Core
77
{
88
internal abstract class ImplicitTransactionBase : 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 ImplicitTransactionBase(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: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,45 @@
11
#if !NETSTANDARD1_3
2+
using System;
23
using System.Transactions;
34
using MySql.Data.MySqlClient;
5+
using MySqlConnector.Utilities;
46

57
namespace MySqlConnector.Core
68
{
79
internal sealed class StandardImplicitTransaction : ImplicitTransactionBase
810
{
9-
public StandardImplicitTransaction(MySqlConnection connection) : base(connection)
11+
public StandardImplicitTransaction(Transaction transaction, MySqlConnection connection)
12+
: base(transaction, connection)
1013
{
1114
}
1215

1316
protected override void OnStart()
1417
{
15-
System.Data.IsolationLevel isolationLevel;
18+
string isolationLevel;
1619
switch (Transaction.IsolationLevel)
1720
{
1821
case IsolationLevel.Serializable:
19-
isolationLevel = System.Data.IsolationLevel.Serializable;
20-
break;
21-
case IsolationLevel.RepeatableRead:
22-
isolationLevel = System.Data.IsolationLevel.RepeatableRead;
22+
isolationLevel = "serializable";
2323
break;
2424
case IsolationLevel.ReadCommitted:
25-
isolationLevel = System.Data.IsolationLevel.ReadCommitted;
25+
isolationLevel = "read committed";
2626
break;
2727
case IsolationLevel.ReadUncommitted:
28-
isolationLevel = System.Data.IsolationLevel.ReadUncommitted;
28+
isolationLevel = "read uncommitted";
2929
break;
3030
case IsolationLevel.Snapshot:
31-
isolationLevel = System.Data.IsolationLevel.Snapshot;
32-
break;
3331
case IsolationLevel.Chaos:
34-
isolationLevel = System.Data.IsolationLevel.Chaos;
35-
break;
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
3634
case IsolationLevel.Unspecified:
35+
case IsolationLevel.RepeatableRead:
3736
default:
38-
isolationLevel = System.Data.IsolationLevel.Unspecified;
37+
isolationLevel = "repeatable read";
3938
break;
4039
}
41-
m_transaction = Connection.BeginTransaction(isolationLevel);
40+
41+
using (var cmd = new MySqlCommand("set transaction isolation level " + isolationLevel + "; start transaction;", Connection))
42+
cmd.ExecuteNonQuery();
4243
}
4344

4445
protected override void OnPrepare(PreparingEnlistment enlistment)
@@ -47,17 +48,15 @@ protected override void OnPrepare(PreparingEnlistment enlistment)
4748

4849
protected override void OnCommit(Enlistment enlistment)
4950
{
50-
m_transaction.Commit();
51-
m_transaction = null;
51+
using (var cmd = new MySqlCommand("commit;", Connection))
52+
cmd.ExecuteNonQuery();
5253
}
5354

5455
protected override void OnRollback(Enlistment enlistment)
5556
{
56-
m_transaction.Rollback();
57-
m_transaction = null;
57+
using (var cmd = new MySqlCommand("rollback;", Connection))
58+
cmd.ExecuteNonQuery();
5859
}
59-
60-
MySqlTransaction m_transaction;
6160
}
6261
}
6362
#endif

src/MySqlConnector/Core/XaImplicitTransaction.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ namespace MySqlConnector.Core
88
{
99
internal sealed class XaImplicitTransaction : ImplicitTransactionBase
1010
{
11-
public XaImplicitTransaction(MySqlConnection connection)
12-
: base(connection)
11+
public XaImplicitTransaction(Transaction transaction, MySqlConnection connection)
12+
: base(transaction, connection)
1313
{
1414
}
1515

0 commit comments

Comments
 (0)