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)

Reply via email to