BUG #5177: Concurrency problem in AbstractJdbc23PooledConnection

From: "Mauro Molinari" <mauro(dot)molinari(at)cardinis(dot)com>
To: pgsql-bugs(at)postgresql(dot)org
Subject: BUG #5177: Concurrency problem in AbstractJdbc23PooledConnection
Date: 2009-11-10 17:41:46
Message-ID: 200911101741.nAAHfkHV010416@wwwmaster.postgresql.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs pgsql-jdbc


The following bug has been logged online:

Bug reference: 5177
Logged by: Mauro Molinari
Email address: mauro(dot)molinari(at)cardinis(dot)com
PostgreSQL version: 8.3.8
Operating system: Linux
Description: Concurrency problem in AbstractJdbc23PooledConnection
Details:

Hello, we're using PostgreSQL JDBC3 driver 8.3-605 to connect to a 8.3.8
Postgres instance. Our application has a JTA-XA transaction infrastructure
managed by Spring and using JBoss Transactions as a JTA implementation.
We're using a connection pool of our own to pool XA connections on top of
which there's JBoss Transactions transactional driver that is managing
connections. Our connection pool infrastructure creates a PGXADataSource
from which it gets new XA connections.

In this scenario, sometimes happens that the PostgreSQL driver fails with
the following exception:

java.lang.NullPointerException
at
org.postgresql.ds.jdbc23.AbstractJdbc23PooledConnection$ConnectionHandler.in
voke(AbstractJdbc23PooledConnection.java:319)
at $Proxy5.close(Unknown Source)
at
com.arjuna.ats.internal.jdbc.ConnectionImple.close(ConnectionImple.java:369)

at
org.springframework.jdbc.datasource.DataSourceUtils.doReleaseConnection(Data
SourceUtils.java:313)
at
org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy$Transact
ionAwareInvocationHandler.invoke(TransactionAwareDataSourceProxy.java:200)
at $Proxy4.close(Unknown Source)
[...]

Looking at the JDBC driver source code, it seems a concurrency problem,
because at row 304-305 the variable con is checked against null.

What is actually happening here is that our code is closing a connection
used to read some data from the DB. This read operation is executed outside
any transaction, so JBoss Transactions is honouring the connection close
request by first calling calling close on the XA connection (and this is
causing the XA connection to be given back to our pool); after that, because
of the actual JDBC connection reports false on isClosed(), JBoss
Transactions is also calling close() on it too... and this generates the
NullPointerException given above.

Looking at the AbstractJdbc23PooledConnection it seems there's no
synchronization at all between isClosed() and close(). My suspect is that in
the previous scenario something like this happens:
1. thread 1: close() is invoked
2. thread 2: isClosed() returns false
3. thread 2: close() is invoked

At operation 2., isClose returns false, while it should return true because
a close request has already been made on thread 1. Anyway, there should be
no problem at all to call close repeatedly on the same connection (as the
JDBC contract states), so the NullPointerException should not happen in any
case.

Please note that:
1. the problem only happens rarely
2. we have no problem at all when we connect to a SQL Server or Oracle
instance
These two considerations lead to think that our JTA-XA infrastructure
behaves correctly.

Thanks in advance and please let me know how I can monitor this bug report
(is there any bug tracking system for PostgreSQL?).

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Boh Yap 2009-11-10 20:45:06 BUG #5178: make check fails because of locale en_AU.US-ASCII
Previous Message Helge Milde 2009-11-10 14:39:23 Re: BUG #5176: database recovery produces infinite loop

Browse pgsql-jdbc by date

  From Date Subject
Next Message Michael Mangeng 2009-11-11 13:48:55 Read Timeout
Previous Message cholid 2009-11-05 15:50:03 Database connection error, try to reset the connection parameters