Re: Deadlock in Oracle JDBC driver (9.2)

From: Robert Klemme <shortcutter_at_googlemail.com>
Date: Fri, 22 Sep 2006 00:06:19 +0200
Message-ID: <4nggmsFa8cp9U2_at_individual.net>


andy.malakov_at_gmail.com wrote:
> Hello All,
>
> I would like to get some advise. We have Java application server
> (Tomcat) that periodically (approximately every other day) experiences
> Java-level deadlocks in JDBC code. We have full thread dumps. Please
> look into the snapshot thread dump (below).
>
> One thread of our code performs a lot of JDBC reads, which deep inside
> obtain few low-level locks (first on oracle.jdbc.ttc7.TTC7Protocol,
> then oracle.jdbc.driver.OracleConnection).
>
> The same locks are being obtained IN REVERSE ORDER by another thread
> (GC Finalizer) that is trying to garbage-collect a PreparedStatement
> object that was created for the same connection.
>
> I can see only one way of fixing this problem - patching our code that
> releases prepared statements to get access to Oracle guts and try to
> obtain an additional lock on TTC7Protocol (so that lock order will
> correspond to the first thread). Oracle JDBC sources are not available,
> so we have to disassemble them. There is no guarantee that this patch
> will not introduce new deadlocks.

I can see another potential solution: notice that the finalizer invokes PS.close()? Your code probably does not invoke close() before it releases the last reference to the PS. So the close has to be done in the finalizer's thread which causes the behavior you see.

My solution to preventing this is to do it in finally blocks:

PS ps = conn.prepareStatement(sql);
// no code here that can throw!
try {

   // use ps
}
finally {

   ps.close();
}

Kind regards

        robert Received on Fri Sep 22 2006 - 00:06:19 CEST

Original text of this message