Florent Guillaume created DBCP-568:
--------------------------------------
Summary: ManagedConnection must clear its cached state after
transaction completes
Key: DBCP-568
URL: https://issues.apache.org/jira/browse/DBCP-568
Project: Commons DBCP
Issue Type: Bug
Affects Versions: 2.0
Reporter: Florent Guillaume
There's a spurious log (see log in comment) about failure to rollback a
connection in the following context:
* use of a managed connection
* cacheState=true (the default)
* rollback initiated by the transaction manager
* rollbackOnReturn=true (the default)
* JDBC driver that refuses to rollback when autoCommit=true (like the
PostgreSQL driver)
The sequence of events leading to the error is:
* transaction started
* application acquires managed connection from pool (wrapping the low-level
PgConnection)
** connection enlisted in transaction
** LocalXAConnectionFactory.LocalXAResource.start sets low-level connection
autoCommit=false
* application does some work
* application check connection's autoCommit state for various reasons
** calls DelegatingConnection.getAutoCommit which caches the state (false)
* application does more work and signals the transaction manager to rollback
* transaction manager rolls back
** all enlisted resources roll back
*** LocalXAConnectionFactory.LocalXAResource.rollback rolls back and sets
low-level autoCommit=true
* managed connection is closed
** PoolableConnection.close calls PoolableConnectionFactory.passivateObject
** passivation does rollback-on-return which checks for connection autoCommit
before doing rollback
*** the autoCommit status returned is the one cached in DelegatingConnection
so still false
*** rollback is called on low-level connection, which throws because it's
still in state autoCommit=true
There are several workarounds:
* use cacheState=false in the datasource config
* use rollbackOnReturn=false in the datasource config
But the correct fix is to make the DelegatingConnection aware that during
rollback something was changed at low-level and its cache is invalid. This can
be done by making ManagedConnection.transactionComplete (which is called in
afterCompletion) clear the cached state.
--
This message was sent by Atlassian Jira
(v8.3.4#803005)