You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "Gary D. Gregory (Jira)" <ji...@apache.org> on 2021/01/13 19:34: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=17264381#comment-17264381 ] 

Gary D. Gregory commented on DBCP-568:
--------------------------------------

[~fguillaume]

Thank you for the detailed write up. Your explanation makes the PR much easier to understand.

 

> 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: 50m
>  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)