-
Notifications
You must be signed in to change notification settings - Fork 38.6k
Description
Thomas Vahrst opened SPR-11876 and commented
DefaultTransactionStatus delegates the method invocation 'isGlobalRollbackOnly' to the internal referenced transaction object. Typically, this object has the type SmartTransactionObject. 'isGlobalRollbackOnly' asserts this with a instanceof check:
public boolean isGlobalRollbackOnly() {
return ((this.transaction instanceof SmartTransactionObject) &&
((SmartTransactionObject) this.transaction).isRollbackOnly());
}
With WebSphereUowTransactionManager, this transaction object is a inner class of WebSphereUowTransactionManager called UOWActionAdapter, which does not implement SmartTransactionObject.
This leads to DefaultTransactionStatus always returning false for 'isGlobalRollbackOnly'.
In our case, we got a problem with two nested Spring TransactionTemplates (Propagation TX_REQUIRED): when the inner TransactionTemplate causes a rollback and the outer transaction template checks this with txStatus.isRollbackOnly(), it will get 'false'.
From AbstractTransactionStatus:
public boolean isRollbackOnly() {
return (isLocalRollbackOnly() || isGlobalRollbackOnly());
}
For the outer TransactionTemplate, localRollbackOnly is false (this is correct) but globalRollbackOnly should be true (but is also false because of WebSphereUowTransactionManager)
Our workaround: We solved this with a copy of WebsphereUowTranasctionManager and changing the inner class UOWActionAdapter to implement SmartTransactionObject
...
/**
* Adapter that executes the given Spring transaction within the WebSphere UOWAction shape.
*/
private class UOWActionAdapter<T> implements UOWAction, SmartTransactionObject {
...
@Override
public boolean isRollbackOnly() {
return uowManager.getRollbackOnly();
}
@Override
public void flush() {
// don't know what to do here...
}
Affects: 3.2.9, 4.0.5
Backported to: 3.2.10
1 votes, 2 watchers
Activity