db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Bryan Pendleton (JIRA)" <j...@apache.org>
Subject [jira] Commented: (DERBY-2689) Deadlock with GenericPreparedStatement
Date Wed, 06 Jun 2007 04:10:25 GMT

    [ https://issues.apache.org/jira/browse/DERBY-2689?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12501786
] 

Bryan Pendleton commented on DERBY-2689:
----------------------------------------

Hi Manish, that is a great point.  I think that calling finish() on a PreparedStatement
doesn't mean that the entire statement is finished off, just that this particular
activation is finished off. The activations seem to maintain an "inUseCount"
reference count on the statement, and calling finish() for a particular activation
just decrements the reference count, and only reclaims the entire statement if
the inUseCount has gone to 0.

In the case I looked at in the debugger, however, the inUseCount is nowhere close
to 0; it is in fact 60. So the statement is not finished, just this particular activation.

It seems that closing an activation requires that we synchronize on the statement
in order to decrement the inUseCount, so this means that as part of initializing
a new activation for one statement, we may decide to close an activation for
some other statement, and since there is no inherent ordering to these reclaimable
activations, we have the situation that one thread which is trying to initialize an
activation for statement A is trying to close an activation for statement B, while another
thread which is trying to initialize an activation for statement B is trying to close
an activation for statement A.

I agree with the assessment that this is a classical deadlock due to a lack of
lock ordering for the synchronization on the various statement objects.

I can see several possibilities:
 - don't try to reclaim activations from inside of addActivation (that is, revert that
   part of the DERBY-418 change). This would of course re-introduce that memory leak.
 - Move the code which reclaims activations to some other location, where it is
   safer to call, because we aren't calling it while holding any statements locked.
 - Change the code which reclaims activations so that it only closes those
   activations which are for the statement that we already have locked, and not
   for any other statements. This might render this code much less effective.
 - Introduce some sort of ordering of statement objects, and only reclaim
   activations for statements which have a higher ordering than ourselves. Since
   the statement locks would then be ordered, the code would not deadlock.

I'm sure there are a number of other ways to look at this, I just wanted to add my thoughts.


> Deadlock with GenericPreparedStatement
> --------------------------------------
>
>                 Key: DERBY-2689
>                 URL: https://issues.apache.org/jira/browse/DERBY-2689
>             Project: Derby
>          Issue Type: Bug
>          Components: JDBC
>    Affects Versions: 10.2.2.0
>         Environment: Windows
>            Reporter: Marc Ewert
>         Attachments: TestDerbyPreparedStatements.java
>
>
> We encountered two times a deadlock inside of derby. It seems that we can't workaround
it. The involved two threads are attached, it looks like a classical deadlock:
> "Thread-22" daemon prio=6 tid=0x0cdaa400 nid=0x1c0 waiting for monitor entry [0x1317f000..0x1317fd4c]
>    java.lang.Thread.State: BLOCKED (on object monitor)
> 	at org.apache.derby.impl.sql.GenericPreparedStatement.finish(Unknown Source)
> 	- waiting to lock <0x052f4d70> (a org.apache.derby.impl.sql.GenericPreparedStatement)
> 	at org.apache.derby.impl.sql.execute.BaseActivation.close(Unknown Source)
> 	at org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.addActivation(Unknown
Source)
> 	at org.apache.derby.impl.sql.execute.BaseActivation.initFromContext(Unknown Source)
> 	at org.apache.derby.impl.services.reflect.LoadedGeneratedClass.newInstance(Unknown Source)
> 	at org.apache.derby.impl.services.reflect.ReflectGeneratedClass.newInstance(Unknown
Source)
> 	at org.apache.derby.impl.sql.GenericActivationHolder.<init>(Unknown Source)
> 	at org.apache.derby.impl.sql.GenericPreparedStatement.getActivation(Unknown Source)
> 	- locked <0x05306f88> (a org.apache.derby.impl.sql.GenericPreparedStatement)
> 	at org.apache.derby.impl.jdbc.EmbedPreparedStatement.<init>(Unknown Source)
> 	at org.apache.derby.impl.jdbc.EmbedPreparedStatement20.<init>(Unknown Source)
> 	at org.apache.derby.impl.jdbc.EmbedPreparedStatement30.<init>(Unknown Source)
> 	at org.apache.derby.impl.jdbc.EmbedPreparedStatement40.<init>(Unknown Source)
> 	at org.apache.derby.jdbc.Driver40.newEmbedPreparedStatement(Unknown Source)
> 	at org.apache.derby.impl.jdbc.EmbedConnection.prepareStatement(Unknown Source)
> 	- locked <0x047beb00> (a org.apache.derby.impl.jdbc.EmbedConnection40)
> 	at org.apache.derby.impl.jdbc.EmbedConnection.prepareStatement(Unknown Source)
>         [custom methods]
> "ThreadPoolThread-SyncScheduler-3-1" prio=2 tid=0x0e620400 nid=0xfec waiting for monitor
entry [0x10a7e000..0x10a7fa14]
>    java.lang.Thread.State: BLOCKED (on object monitor)
> 	at org.apache.derby.impl.sql.GenericPreparedStatement.finish(Unknown Source)
> 	- waiting to lock <0x05306f88> (a org.apache.derby.impl.sql.GenericPreparedStatement)
> 	at org.apache.derby.impl.sql.execute.BaseActivation.close(Unknown Source)
> 	at org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.addActivation(Unknown
Source)
> 	at org.apache.derby.impl.sql.execute.BaseActivation.initFromContext(Unknown Source)
> 	at org.apache.derby.impl.services.reflect.LoadedGeneratedClass.newInstance(Unknown Source)
> 	at org.apache.derby.impl.services.reflect.ReflectGeneratedClass.newInstance(Unknown
Source)
> 	at org.apache.derby.impl.sql.GenericActivationHolder.<init>(Unknown Source)
> 	at org.apache.derby.impl.sql.GenericPreparedStatement.getActivation(Unknown Source)
> 	- locked <0x052f4d70> (a org.apache.derby.impl.sql.GenericPreparedStatement)
> 	at org.apache.derby.impl.jdbc.EmbedPreparedStatement.<init>(Unknown Source)
> 	at org.apache.derby.impl.jdbc.EmbedPreparedStatement20.<init>(Unknown Source)
> 	at org.apache.derby.impl.jdbc.EmbedPreparedStatement30.<init>(Unknown Source)
> 	at org.apache.derby.impl.jdbc.EmbedPreparedStatement40.<init>(Unknown Source)
> 	at org.apache.derby.jdbc.Driver40.newEmbedPreparedStatement(Unknown Source)
> 	at org.apache.derby.impl.jdbc.EmbedConnection.prepareStatement(Unknown Source)
> 	- locked <0x04225178> (a org.apache.derby.impl.jdbc.EmbedConnection40)
> 	at org.apache.derby.impl.jdbc.EmbedConnection.prepareStatement(Unknown Source)
>         [custom methods]

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


Mime
View raw message