Bug #39817 Transaction Dispose does not roll back
Submitted: 2 Oct 2008 17:00 Modified: 10 Oct 2008 11:01
Reporter: Daniel Cheramie Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / NET Severity:S2 (Serious)
Version:5.2, 5.3 OS:Any
Assigned to: CPU Architecture:Any
Tags: Dispose, rollback, transaction

[2 Oct 2008 17:00] Daniel Cheramie
Description:
Build-in Microsoft transactions for other DB providers provide the following:

using(DbTransaction lTrans = CreateMyTransaction())
{
    // Do some stuff
    if(failed)
        throw new Exception();
    lTrans.Commit();
}

If the exception is thrown, the transaction object is disposed and the transaction is rolled back. This is not the case with MySqlTransaction, as the dispose function is ignored completely.

How to repeat:
Create a transaction via a using block as shown and do not call Commit or Rollback on it. Check database server and note if there is a transaction that is now stuck open. Mine stuck around for an hour while I tracked down the problem.

Suggested fix:
Modify transaction class to override the base class's void Dispose(bool) and call RollBack as needed.
[2 Oct 2008 17:45] Tonci Grgin
Hi Daniel and thanks for your report.

Verified by looking into code. Truly there is no rollback called in dispose of DBTransaction. This is actually a feature request so please change severity to S4.
[2 Oct 2008 18:12] Daniel Cheramie
I marked this as critical because it is. I have seen this design pattern over and over in code, including throughout my own, and as I mentioned, Microsoft does this with the three providers that ship with the .NET Framework. Other factors 
include:

* The workaround is non-trivial if you use the MySqlTransaction type throughout your code. Fortunately, I use the DbTransaction type everywhere I deal with it, so I was able to write a DbTransaction class which wraps another transaction and ensures rollback.

* The other workaround is to use a try/finally block, but this needs done everywhere a transaction is used.

* This bug causes severe consequences. In my case, my entire program was unable to access the database because of the locks held by this "forgotten" transaction.

* If this is not intended use, then the transaction should not be implementing IDisposable. IDisposable says "The primary use of this interface is to release unmanaged resources." It fails to do so.
[8 Oct 2008 18: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/55802
[8 Oct 2008 18:46] Reggie Burnett
fixed in 5.0.10, 5.1.8, and 5.2.4+
[10 Oct 2008 11:01] Tony Bedford
Entries were added to the 5.0.10, 5.1.8 and 5.2.4 changelogs:

If, when using the MySqlTransaction transaction object, an exception was thrown, the transaction object was not disposed of and the transaction was not rolled back.