[ 
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)

Reply via email to