Issue Details (XML | Word | Printable)

Key: DERBY-2142
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Major Major
Assignee: Kathey Marsden
Reporter: Asif H. Shahid
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
Derby

NullPointerException while using XAConnection/PooledConnection in a heavily contended multithreaded scenario

Created: 04/Dec/06 10:54 AM   Updated: 01/Feb/08 07:59 PM
Return to search
Component/s: JDBC
Affects Version/s: 10.0.2.0, 10.0.2.1, 10.1.1.0, 10.1.2.1, 10.1.3.1, 10.2.1.6
Fix Version/s: 10.1.3.2, 10.2.2.1, 10.3.3.0, 10.4.1.3

Time Tracking:
Not Specified

File Attachments:
  Size
Text File Licensed for inclusion in ASF works derby-2142_diff.txt 2008-01-26 12:39 AM Kathey Marsden 0.6 kB
Text File Licensed for inclusion in ASF works derby-2142_diff2.txt 2008-01-28 10:04 PM Kathey Marsden 2 kB
Text File Licensed for inclusion in ASF works derby-2142_diff3.txt 2008-01-28 11:19 PM Kathey Marsden 2 kB
Text File Licensed for inclusion in ASF works derby-2142_stat.txt 2008-01-26 12:39 AM Kathey Marsden 0.1 kB
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.
Issue Links:
Reference
 

Urgency: Normal
Resolution Date: 01/Feb/08 07:59 PM


 Description  « Hide
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;
}










 All   Comments   Work Log   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Repository Revision Date User Message
ASF #616141 Tue Jan 29 02:26:01 UTC 2008 kmarsden DERBY-2142 NullPointerException while using XAConnection/PooledConnection in a heavily contended multithreaded scenario

core fix contributed by Asif Shahid with further suggestions from Dan Debrunner
Files Changed
MODIFY /db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbedPooledConnection.java

Repository Revision Date User Message
ASF #616177 Tue Jan 29 06:06:30 UTC 2008 djd DERBY-2142 (test) Add a fixture (testPooledReuseOnClose) to DataSourceTest that tests the fix to DERBY-2142. It failed before revision 616141 and passed after for embedded, but fails for network client so it is disabled for that env.
Files Changed
MODIFY /db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DataSourceTest.java

Repository Revision Date User Message
ASF #616575 Wed Jan 30 01:12:01 UTC 2008 kmarsden DERBY-2142 NullPointerException while using XAConnection/PooledConnection in a heavily contended multithreaded scenario

Update code comments.
Files Changed
MODIFY /db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbedPooledConnection.java

Repository Revision Date User Message
ASF #616880 Wed Jan 30 20:01:32 UTC 2008 kmarsden DERBY-2142 NullPointerException while using XAConnection/PooledConnection in a heavily contended multithreaded scenario

port from trunk revision 616141, 616177, 616575
Files Changed
MODIFY /db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/junit/JDBCDataSource.java
MODIFY /db/derby/code/branches/10.3/java/engine/org/apache/derby/jdbc/EmbedPooledConnection.java
MODIFY /db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DataSourceTest.java

Repository Revision Date User Message
ASF #616966 Thu Jan 31 00:24:10 UTC 2008 kmarsden DERBY-2142 NullPointerException while using XAConnection/PooledConnection in a heavily contended multithreaded scenario
port from trunk, revisions 616141,616575
Files Changed
MODIFY /db/derby/code/branches/10.2/java/engine/org/apache/derby/jdbc/EmbedPooledConnection.java

Repository Revision Date User Message
ASF #617145 Thu Jan 31 15:05:29 UTC 2008 kmarsden DERBY-2142 NullPointerException while using XAConnection/PooledConnection in a heavily contended multithreaded scenario

port from trunk revision 616141, 616575
Files Changed
MODIFY /db/derby/code/branches/10.1/java/engine/org/apache/derby/jdbc/EmbedPooledConnection.java

Repository Revision Date User Message
ASF #619695 Fri Feb 08 00:14:12 UTC 2008 djd Expand the DataSourceTest testing added in DERBY-2142 to include closing the PooledConnection during a callback resulting from a close on its logical connection.
Files Changed
MODIFY /db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DataSourceTest.java