[ http://issues.apache.org/jira/browse/DERBY-2142?page=all ]
Rick Hillegas updated DERBY-2142: --------------------------------- Urgency: Normal (was: Urgent) Priority: Major (was: Critical) Adjusting urgency and priority to the standard levels. > NullPointerException while using XAConnection/PooledConnection in a heavily > contended multithreaded scenario > ------------------------------------------------------------------------------------------------------------ > > Key: DERBY-2142 > URL: http://issues.apache.org/jira/browse/DERBY-2142 > Project: Derby > Issue Type: Bug > Components: JDBC > Affects Versions: 10.0.2.0, 10.0.2.1, 10.1.1.0, 10.2.1.6, 10.1.2.1, > 10.1.3.1 > 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 > > 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-10.2.1.6-src & 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 () as > 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. - If you think it was sent incorrectly contact one of the administrators: http://issues.apache.org/jira/secure/Administrators.jspa - For more information on JIRA, see: http://www.atlassian.com/software/jira