db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Daniel John Debrunner (JIRA)" <j...@apache.org>
Subject [jira] Commented: (DERBY-2142) NullPointerException while using XAConnection/PooledConnection in a heavily contended multithreaded scenario
Date Mon, 28 Jan 2008 20:27:34 GMT

    [ https://issues.apache.org/jira/browse/DERBY-2142?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12563276#action_12563276

Daniel John Debrunner commented on DERBY-2142:

>> "Since the listeners can get a handed to the PooledConnection or XAConnection &
XAResource we would just have to ensure that any method they can call on those interfaces
behaves correctly."
> What exactly do I need to be checking?

Nothing. :-)

It's covered by my recent comment which probably was posted while you were writing yours.

Sections 11.2 and 12.5 state that at the time of the callback they can return the PooledConnection
to the pool for re-use, thus at time of the callback the PooledConnection must be disassociated
from its previous logical connection. Note the logical connection is being closed, not the
pooled connection.

The buggy code passes the PooledConnection to the callbacks in a state where it is still associated
to the just closed logical connection, my original concern was what is the expected state
of the PooledConnection for the listeners: still associated or disassociated. I hadn't researched
the details then.

> NullPointerException while using XAConnection/PooledConnection in a heavily contended
multithreaded scenario
> ------------------------------------------------------------------------------------------------------------
>                 Key: DERBY-2142
>                 URL: https://issues.apache.org/jira/browse/DERBY-2142
>             Project: Derby
>          Issue Type: Bug
>          Components: JDBC
>    Affects Versions:,,,,,
>         Environment: The issue can appear in any environment as the bug is in the source
code . The bug has been verified in Suse Linux env.
>            Reporter: Asif H. Shahid
>            Assignee: Kathey Marsden
>         Attachments: derby-2142_diff.txt, derby-2142_stat.txt
> We are using the Derby's Transactional DataSource  class ( org.apache.derby.jdbc.EmbeddedXADataSource
) to create a pool of  XAConnections in our application.
> Whenever a thread in a JTA transaction requests for a SQLConnection , we retrieve an
XAConnection from the pool. From the XAConnection , we  register the XAResource with the TransactionManager
& return a java.sql.Connection to the application. 
> A class implementing the ConnectionEventListener is registered with the XAConnection
to get callback  connectionClosed ( ) when the thead closes the java.sql.Connection. In this
callback,  we invoke XAResource.end & return the XAConnection to our pool  so that other
threads can use it.
> We have encountered NullPointerException  , when performing operation on java.sql.Connection.
> The stacktrace is as follows
> at
> org.apache.derby.jdbc.XAStatementControl.<init>(XAStatementControl.java:71)
>    at
> org.apache.derby.jdbc.EmbedXAConnection.wrapStatement(EmbedXAConnection.java:162)
>    at
> org.apache.derby.iapi.jdbc.BrokeredConnection.createStatement(Unknown
> Source)
>    at
> com.gemstone.gemfire.internal.datasource.ConnectionPoolingTest$1.run(ConnectionPoolingTest.java:174)
>    at java.lang.Thread.run(Thread.java:595)
> I have done some debugging on source code of  db-derby- & have following
explanation of the bug & a suggested fix. However, I want to confirm that it is genuinely
a bug & not a problem in our understanding of the Datasource spec behaviour.
> Reason for the bug:-
> The class EmbedPooledConnection.java   stores in the field currentConnectionHandle (
of  class BrokeredConnection)  a reference of the java.sql.Connection object , being returned
to the application, 
> Now ,whenever the client closes the java.sql.Connection ,  the code flow is 
> EmbedPooledConnection.close() --> EmbedPooledConnection.notifyClose().
> In the function EmbedPooledConnection.notifyClose(), it notifies  my listener ( javax.sql.ConnectionEventListener)
) where I return the XAConnection to the pool ( after deregistering the XAResource). 
> The last line of EmbedPooledConnection.close()  makes the currentConnectionHandle  field
as null.
> The issue here is that  javax.sql.ConnectionEventListener.connectionClosed is invoked
before making the currentConenctionHandle field as null.  Thus XAConnection is returned to
the pool , ready for pickup by a new thread. This new thread obtains a java.sql.Connection
whose reference gets assigned to the currentConnectionHandle field, meanwhile the previous
thread completes the EmbedPooledConnection.close  making the newly assigned currentConnectionHandle
as null.
> Thus a previous thread's close makes a field null of an XAConnection, which has been
assigned to a new thread.
> The bug is easily reproducible  in a multi threaded scenario ( 20 threads or so) with
a pool size of around 4 XAConnections so that there is heavy  contention on XAConnection.

> The fix is to rearrange the code of EmbedPooledConenction.java 's closingConnection ()
> bug :
> public  boolean closingConnection() {
>      notifyClose();
>      currentConnectionHandle = null;
>     return false;
> }
> bug fix :
> public  boolean closingConnection() {
>      currentConnectionHandle = null;
>      notifyClose();
>      return false;
> }

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

View raw message