Details
-
Bug
-
Status: Closed
-
Minor
-
Resolution: Fixed
-
2.0
-
None
-
Patch
Description
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
- all enlisted resources roll back
- 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.
Attachments
Issue Links
- links to