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 2020/11/15 18:46:00 UTC

[jira] [Commented] (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: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)