[
https://issues.apache.org/jira/browse/DBCP-568?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17232375#comment-17232375
]
Florent Guillaume commented on DBCP-568:
----------------------------------------
Example stacktrace logged
{noformat}
2020-11-15 16:16:10,455 [mythread] WARN [SwallowedExceptionLogger] An internal
object pool swallowed an Exception.
org.postgresql.util.PSQLException: Cannot rollback when autoCommit is enabled.
at org.postgresql.jdbc.PgConnection.rollback(PgConnection.java:895)
~[postgresql-42.2.18.jar:42.2.18]
at
org.apache.commons.dbcp2.DelegatingConnection.rollback(DelegatingConnection.java:482)
~[commons-dbcp2-2.8.0.jar:2.8.0]
at
org.apache.commons.dbcp2.PoolableConnectionFactory.passivateObject(PoolableConnectionFactory.java:427)
~[commons-dbcp2-2.8.0.jar:2.8.0]
at
org.apache.commons.pool2.impl.GenericObjectPool.returnObject(GenericObjectPool.java:557)
~[commons-pool2-2.9.0.jar:2.9.0]
at
org.apache.commons.dbcp2.PoolableConnection.close(PoolableConnection.java:203)
~[commons-dbcp2-2.8.0.jar:2.8.0]
at
org.apache.commons.dbcp2.DelegatingConnection.closeInternal(DelegatingConnection.java:236)
~[commons-dbcp2-2.8.0.jar:2.8.0]
at
org.apache.commons.dbcp2.DelegatingConnection.close(DelegatingConnection.java:207)
~[commons-dbcp2-2.8.0.jar:2.8.0]
at
org.apache.commons.dbcp2.managed.ManagedConnection.close(ManagedConnection.java:111)
~[commons-dbcp2-2.8.0.jar:2.8.0]
at com.example.MyApp.closeConnection(MyApp.java:42)
{noformat}
> 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
> Time Spent: 10m
> 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)