[Mono-bugs] [Bug 421491] "Could not allocate new OCI Handle of type Statement" message when accessing Oracle

bugzilla_noreply at novell.com bugzilla_noreply at novell.com
Wed Aug 10 11:37:35 EDT 2011


https://bugzilla.novell.com/show_bug.cgi?id=421491

https://bugzilla.novell.com/show_bug.cgi?id=421491#c11


--- Comment #11 from Dan McFadyen <danm at cryptocard.com> 2011-08-10 15:37:32 UTC ---
I figured out the issue.

When using connection pooling, any OracleConnection object that gets leaked
without being closed will cause a problem.

The problem being is that because there are no references to the
OracleConnection object any more, the GC will do it's job and dispose the
object. The OracleConnection.Dispose function calls close. Any connection that
gets close called on it while it's part of connection pooling will re-add
itself to the connection pool.

Because there are still references to the pool from other static members, it's
still a valid object. So the dispose function happily re-adds a disposed
connection object back into the pool, then cleans itself up.

The connection is then sitting in the pool as a ticking time bomb for the next
time it's used.

I have no idea what the effects of having references to a GC disposed object
around are, but they can't be good. Even worse, I figured out that the parenth
IntPtr that was null from my last comment, is actually a 'this' reference that
is null.

The only fix I can see is in the OracleConnection.cs file, in the Dispose
function, just before you call Close, set pooling to false, and pool = null.


[MonoTODO]
protected override void Dispose (bool disposing)
{
    if (!disposed) {
->        pooling = false;
->        pool = null;
        if (State == ConnectionState.Open)
            Close ();
        dataReader = null;
        transaction = null;
        oci = null;
        pool = null;
        conInfo.Username = string.Empty;
        conInfo.Database = string.Empty;
        conInfo.Password = string.Empty;
        connectionString = null;
        parsedConnectionString = null;
        base.Dispose (disposing);
        disposed = true;
    }
}


Obvious downside here is that any connection you leak won't go back to the pool
and you lose the speed benefit of it. But the only way you could keep the
dispose from being called would be to keep references to it somewhere, which
then you'd have no way of knowing if the connections are leaked.

A bit of performance seems a fair price to pay if connections are being leaked
as it's a bad thing to do. But avoiding a crash is probably much nicer.

I hope that even if you can't reproduce the bug, the description of the
behavior should be enough to get this fixed.

Thanks,

Dan

-- 
Configure bugmail: https://bugzilla.novell.com/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.


More information about the mono-bugs mailing list