You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "Florent Guillaume (Jira)" <ji...@apache.org> on 2021/01/13 19:51:00 UTC
[jira] [Closed] (DBCP-568) ManagedConnection must clear its cached
state after transaction completes
[ https://issues.apache.org/jira/browse/DBCP-568?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Florent Guillaume closed DBCP-568.
----------------------------------
> 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
> Priority: Minor
> Fix For: 2.9.0
>
> Time Spent: 1h
> Remaining Estimate: 0h
>
> 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)