Bug #37991 Connection fails when trying to close after a commit while network to db is bad
Submitted: 9 Jul 2008 14:06 Modified: 30 Oct 2008 11:16
Reporter: Fredrik Wallroth Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / NET Severity:S3 (Non-critical)
Version:5.1.4.0 OS:Microsoft Windows (XP SP2)
Assigned to: CPU Architecture:Any

[9 Jul 2008 14:06] Fredrik Wallroth
Description:
MySql Server version: 5.0.51a-community.

When calling MySqlConnection.Close() it fails with a null reference exception. 

The connection is in a transaction. The network to the server goes down just before commiting the transaction. The commit fails (correctly) due to this, just before Close() is called.

Expected behaviour: MySqlConnection.Close() fails with a MySqlException.

I will soon file a related bug on the server which is much more critical and triggered by this.

How to repeat:
Prerequisities: The database server is not on the same machine as this test is run on.

1) Create a table:

CREATE TABLE `test` (
  `id` bigint(20) NOT NULL auto_increment,
  `value` int(11) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;

2) Create a small test application (for example a windows application with two buttons), with the following code:

private void button3_Click(object sender, EventArgs e)
        {
            _conn = new MySqlConnection("server=servername;Port=port;database=dbname;user id=user;password=password;pooling=true;");

            _conn.Open();

            _trans = _conn.BeginTransaction();

            using (MySqlCommand cmd = new MySqlCommand("insert into test (value) values (2);", _conn))
            {
                cmd.ExecuteNonQuery();
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            try
            {
                _trans.Commit();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception when commiting:");
                Console.WriteLine(ex.ToString());
            }

            try
            {
                _conn.Close();
            }
            catch (Exception ex2)
            {
                Console.WriteLine("Exception when closing conn:");
                Console.WriteLine(ex2.ToString());
            }
        }

3) Replace connection information in the connection string with real values, but make sure "pooling=true" is still there (or is it true by default?).

4) Start the program and trigger the "button3_Click" method.

5) Disable the network connection in windows.

6) Trigger the "button4_Click" method.

You'll get an output like this:

A first chance exception of type 'MySql.Data.MySqlClient.MySqlException' occurred in MySql.Data.dll
Exception when commiting:
MySql.Data.MySqlClient.MySqlException: Writing to the stream failed. ---> System.IO.IOException: Unable to write data to the transport connection: En befintlig anslutning tvingades att stänga av fjärrvärddatorn. ---> System.Net.Sockets.SocketException: En befintlig anslutning tvingades att stänga av fjärrvärddatorn
   at System.Net.Sockets.Socket.Send(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
   at System.Net.Sockets.NetworkStream.Write(Byte[] buffer, Int32 offset, Int32 size)
   --- End of inner exception stack trace ---
   at System.Net.Sockets.NetworkStream.Write(Byte[] buffer, Int32 offset, Int32 size)
   at System.IO.BufferedStream.FlushWrite()
   at System.IO.BufferedStream.Flush()
   at MySql.Data.MySqlClient.MySqlStream.Flush()
   --- End of inner exception stack trace ---
   at MySql.Data.MySqlClient.MySqlStream.Flush()
   at MySql.Data.MySqlClient.NativeDriver.ExecuteCommand(DBCmd cmd, Byte[] bytes, Int32 length)
   at MySql.Data.MySqlClient.NativeDriver.Query(Byte[] bytes, Int32 length)
   at MySql.Data.MySqlClient.Statement.ExecuteNext()
   at MySql.Data.MySqlClient.PreparableStatement.ExecuteNext()
   at MySql.Data.MySqlClient.Statement.Execute()
   at MySql.Data.MySqlClient.PreparableStatement.Execute()
   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.Commit()
   at MySqlConnectorTransactionLockTest.Form1.button4_Click(Object sender, EventArgs e) in Form1.cs:line 94
A first chance exception of type 'System.NullReferenceException' occurred in MySql.Data.dll
Exception when closing conn:
System.NullReferenceException: Object reference not set to an instance of an object.
   at MySql.Data.MySqlClient.NativeDriver.ExecuteCommand(DBCmd cmd, Byte[] bytes, Int32 length)
   at MySql.Data.MySqlClient.NativeDriver.Query(Byte[] bytes, Int32 length)
   at MySql.Data.MySqlClient.Statement.ExecuteNext()
   at MySql.Data.MySqlClient.PreparableStatement.ExecuteNext()
   at MySql.Data.MySqlClient.Statement.Execute()
   at MySql.Data.MySqlClient.PreparableStatement.Execute()
   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.MySqlConnection.CloseFully()
   at MySql.Data.MySqlClient.MySqlConnection.Close()
   at MySqlConnectorTransactionLockTest.Form1.button4_Click(Object sender, EventArgs e) in Form1.cs:line 104

Expected result:
A similar output, but with MySqlException instead of NullReferenceException.

Suggested fix:
Analyze why the unexpected state in the NativeDriver occurs and fix it.
[9 Jul 2008 14:09] Fredrik Wallroth
Forgot those two lines in the reproduce code (on class level):

MySqlTransaction _trans = null;
MySqlConnection _conn;
[9 Jul 2008 14:48] Fredrik Wallroth
See also related bug:
http://bugs.mysql.com/37994
[9 Jul 2008 16:44] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/49326
[9 Jul 2008 16:45] Reggie Burnett
Fixed in 5.1.7 and 5.2.3+
[9 Jul 2008 16:54] Reggie Burnett
Fixed in 5.0.10 too
[11 Jul 2008 12:35] Tony Bedford
An entry has been added to the 5.0.10, 5.1.7, and 5.2.3 changelogs:

Executing a command that resulted in a fatal exception did not close the connection.
[11 Jul 2008 21:47] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/49606
[30 Oct 2008 11:16] Fredrik Wallroth
Thanks!

Fix have been verified to work on v 5.2.3.0.