| Bug #102129 | Hang in MySqlConnection.Close after TransactionScope times out | ||
|---|---|---|---|
| Submitted: | 1 Jan 2021 23:00 | Modified: | 17 Jan 2022 19:21 |
| Reporter: | Bradley Grainger (OCA) | Email Updates: | |
| Status: | Can't repeat | Impact on me: | |
| Category: | Connector / NET | Severity: | S2 (Serious) |
| Version: | 8.0.22 | OS: | Windows (10) |
| Assigned to: | CPU Architecture: | Other (x64) | |
[4 Jan 2021 6:30]
MySQL Verification Team
Hello Bradley, Thank you for the report and test case. With the provided test case I'm getting below Unhandled Exception: - C/NET 8.0.22, VS 2019, .NET framework 4.8 using MySql.Data.MySqlClient; using System; using System.Transactions; namespace Bug102129 { class Program { static void Main(string[] args) { var transactionScope = new TransactionScope(TransactionScopeOption.Required, TimeSpan.FromSeconds(1)); var connection = new MySqlConnection("server=xxx;port=3333;userid = ushastry; password = mysql123;AutoEnlist=true"); connection.Open(); Console.WriteLine("Executing command"); using (var command = new MySqlCommand("DO SLEEP(2);", connection)) command.ExecuteNonQuery(); Console.WriteLine("Executed command"); connection.Close(); // delays for 30 seconds; then sometimes succeeds, sometimes throws NullReferenceException connection.Dispose(); Console.WriteLine("Closed connection"); transactionScope.Complete(); } } } Unhandled Exception: System.Transactions.TransactionAbortedException: The transaction has aborted. at MySql.Data.MySqlClient.Interceptors.ExceptionInterceptor.Throw(Exception exception) at MySql.Data.MySqlClient.MySqlConnection.Throw(Exception ex) at MySql.Data.MySqlClient.MySqlCommand.Throw(Exception ex) at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior) at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader() at MySql.Data.MySqlClient.Driver.LoadServerProperties(MySqlConnection connection) at MySql.Data.MySqlClient.Driver.Configure(MySqlConnection connection) at MySql.Data.MySqlClient.MySqlConnection.Open() at Bug102129.Program.Main(String[] args) in C:\Work\MySQLNet\Bug102129\Bug102129\Program.cs:line 14 Press any key to continue . . . Am I missing anything here? Please let me know. Thank you! regards, Umesh
[13 Jan 2021 14:07]
Bradley Grainger
I tested this again. I don't get the exception I reported when targeting "net48" (.NET Framework 4.8), but I do get it when targeting "net5.0" (.NET 5.0). So it appears this bug may be framework-specific.
[18 Jan 2021 8:24]
MySQL Verification Team
Thank you for the feedback.
[17 Jan 2022 19:21]
Daniel Valdez
Posted by developer: Could not be reproduced using the latest release of Connector/NET, v8.0.27.

Description: After a System.Transactions.Transaction (that a connection is enlisted in) times out, calling MySqlConnection.Close just hangs for DefaultCommandTimeout seconds. After the hang, the call to Close sometimes succeeds, but sometimes throws a NullReferenceException: NullReferenceException: Object reference not set to an instance of an object. at MySql.Data.MySqlClient.MySqlDataReader.Close() at MySql.Data.MySqlClient.MySqlConnection.Close() at UserQuery.Main(), line 24 Meanwhile, the transaction throws an exception on a background thread: MySqlException: Fatal error encountered during command execution. at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior) at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader() at MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery() at MySql.Data.MySqlClient.MySqlTransaction.Rollback() at MySql.Data.MySqlClient.MySqlTransactionScope.Rollback(SinglePhaseEnlistment singlePhaseEnlistment) at MySql.Data.MySqlClient.MySqlPromotableTransaction.System.Transactions.IPromotableSinglePhaseNotification.Rollback(SinglePhaseEnlistment singlePhaseEnlistment) at System.Transactions.DurableEnlistmentAborting.EnterState(InternalEnlistment enlistment) at System.Transactions.DurableEnlistmentActive.InternalAborted(InternalEnlistment enlistment) at System.Transactions.TransactionStateAborted.EnterState(InternalTransaction tx) at System.Transactions.TransactionStateActive.Rollback(InternalTransaction tx, Exception e) at System.Transactions.EnlistableStates.Timeout(InternalTransaction tx) at System.Transactions.Bucket.TimeoutTransactions() at System.Transactions.BucketSet.TimeoutTransactions() at System.Transactions.TransactionTable.ThreadTimer(Object state) at System.Threading.TimerQueueTimer.<>c.<.cctor>b__23_0(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) --- End of stack trace from previous location --- at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.TimerQueueTimer.CallCallback(Boolean isThreadPool) at System.Threading.TimerQueueTimer.Fire(Boolean isThreadPool) at System.Threading.TimerQueue.FireNextTimers() at System.Threading.TimerQueue.AppDomainTimerCallback(Int32 id) How to repeat: Run the following C# code, which causes a System.Transactions transaction to time out before the SQL statement has finished executing: var transactionScope = new TransactionScope(TransactionScopeOption.Required, TimeSpan.FromSeconds(1)); var connection = new MySqlConnection("...;AutoEnlist=true"); connection.Open(); Console.WriteLine("Executing command"); using (var command = new MySqlCommand("DO SLEEP(2);", connection)) command.ExecuteNonQuery(); Console.WriteLine("Executed command"); connection.Close(); // delays for 30 seconds; then sometimes succeeds, sometimes throws NullReferenceException connection.Dispose(); Console.WriteLine("Closed connection"); transactionScope.Complete();