WebSphereUowTransactionManager logs overridden application exceptions
Issue: SPR-16102
This commit is contained in:
parent
bf6025303b
commit
efe943df72
|
@ -306,6 +306,8 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
|
|||
}
|
||||
|
||||
else {
|
||||
final ThrowableHolder throwableHolder = new ThrowableHolder();
|
||||
|
||||
// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
|
||||
try {
|
||||
Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr, status -> {
|
||||
|
@ -325,7 +327,8 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
|
|||
}
|
||||
else {
|
||||
// A normal return value: will lead to a commit.
|
||||
return new ThrowableHolder(ex);
|
||||
throwableHolder.throwable = ex;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
|
@ -333,17 +336,28 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
|
|||
}
|
||||
});
|
||||
|
||||
// Check result: It might indicate a Throwable to rethrow.
|
||||
if (result instanceof ThrowableHolder) {
|
||||
throw ((ThrowableHolder) result).getThrowable();
|
||||
}
|
||||
else {
|
||||
return result;
|
||||
// Check result state: It might indicate a Throwable to rethrow.
|
||||
if (throwableHolder.throwable != null) {
|
||||
throw throwableHolder.throwable;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch (ThrowableHolderException ex) {
|
||||
throw ex.getCause();
|
||||
}
|
||||
catch (TransactionSystemException ex2) {
|
||||
if (throwableHolder.throwable != null) {
|
||||
logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
|
||||
ex2.initApplicationException(throwableHolder.throwable);
|
||||
}
|
||||
throw ex2;
|
||||
}
|
||||
catch (Throwable ex2) {
|
||||
if (throwableHolder.throwable != null) {
|
||||
logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
|
||||
}
|
||||
throw ex2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -540,14 +554,10 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
|
|||
ex2.initApplicationException(ex);
|
||||
throw ex2;
|
||||
}
|
||||
catch (RuntimeException ex2) {
|
||||
catch (RuntimeException | Error ex2) {
|
||||
logger.error("Application exception overridden by rollback exception", ex);
|
||||
throw ex2;
|
||||
}
|
||||
catch (Error err) {
|
||||
logger.error("Application exception overridden by rollback error", ex);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// We don't roll back on this exception.
|
||||
|
@ -560,14 +570,10 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
|
|||
ex2.initApplicationException(ex);
|
||||
throw ex2;
|
||||
}
|
||||
catch (RuntimeException ex2) {
|
||||
catch (RuntimeException | Error ex2) {
|
||||
logger.error("Application exception overridden by commit exception", ex);
|
||||
throw ex2;
|
||||
}
|
||||
catch (Error err) {
|
||||
logger.error("Application exception overridden by commit error", ex);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -679,20 +685,12 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
|
|||
|
||||
|
||||
/**
|
||||
* Internal holder class for a Throwable, used as a return value
|
||||
* from a TransactionCallback (to be subsequently unwrapped again).
|
||||
* Internal holder class for a Throwable in a callback transaction model.
|
||||
*/
|
||||
private static class ThrowableHolder {
|
||||
|
||||
private final Throwable throwable;
|
||||
|
||||
public ThrowableHolder(Throwable throwable) {
|
||||
this.throwable = throwable;
|
||||
}
|
||||
|
||||
public final Throwable getThrowable() {
|
||||
return this.throwable;
|
||||
}
|
||||
@Nullable
|
||||
public Throwable throwable;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -261,7 +261,8 @@ public class WebSphereUowTransactionManager extends JtaTransactionManager
|
|||
"Transaction propagation 'nested' not supported for WebSphere UOW transactions");
|
||||
}
|
||||
if (pb == TransactionDefinition.PROPAGATION_SUPPORTS ||
|
||||
pb == TransactionDefinition.PROPAGATION_REQUIRED || pb == TransactionDefinition.PROPAGATION_MANDATORY) {
|
||||
pb == TransactionDefinition.PROPAGATION_REQUIRED ||
|
||||
pb == TransactionDefinition.PROPAGATION_MANDATORY) {
|
||||
joinTx = true;
|
||||
newSynch = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
|
||||
}
|
||||
|
@ -279,7 +280,8 @@ public class WebSphereUowTransactionManager extends JtaTransactionManager
|
|||
"Transaction propagation 'mandatory' but no existing transaction found");
|
||||
}
|
||||
if (pb == TransactionDefinition.PROPAGATION_SUPPORTS ||
|
||||
pb == TransactionDefinition.PROPAGATION_NOT_SUPPORTED || pb == TransactionDefinition.PROPAGATION_NEVER) {
|
||||
pb == TransactionDefinition.PROPAGATION_NOT_SUPPORTED ||
|
||||
pb == TransactionDefinition.PROPAGATION_NEVER) {
|
||||
uowType = UOWSynchronizationRegistry.UOW_TYPE_LOCAL_TRANSACTION;
|
||||
newSynch = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
|
||||
}
|
||||
|
@ -293,6 +295,7 @@ public class WebSphereUowTransactionManager extends JtaTransactionManager
|
|||
logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition);
|
||||
}
|
||||
SuspendedResourcesHolder suspendedResources = (!joinTx ? suspend(null) : null);
|
||||
UOWActionAdapter<T> action = null;
|
||||
try {
|
||||
if (definition.getTimeout() > TransactionDefinition.TIMEOUT_DEFAULT) {
|
||||
uowManager.setUOWTimeout(uowType, definition.getTimeout());
|
||||
|
@ -300,7 +303,7 @@ public class WebSphereUowTransactionManager extends JtaTransactionManager
|
|||
if (debug) {
|
||||
logger.debug("Invoking WebSphere UOW action: type=" + uowType + ", join=" + joinTx);
|
||||
}
|
||||
UOWActionAdapter<T> action = new UOWActionAdapter<>(
|
||||
action = new UOWActionAdapter<>(
|
||||
definition, callback, (uowType == UOWManager.UOW_TYPE_GLOBAL_TRANSACTION), !joinTx, newSynch, debug);
|
||||
uowManager.runUnderUOW(uowType, joinTx, action);
|
||||
if (debug) {
|
||||
|
@ -308,11 +311,15 @@ public class WebSphereUowTransactionManager extends JtaTransactionManager
|
|||
}
|
||||
return action.getResult();
|
||||
}
|
||||
catch (UOWException ex) {
|
||||
throw new TransactionSystemException("UOWManager transaction processing failed", ex);
|
||||
}
|
||||
catch (UOWActionException ex) {
|
||||
throw new TransactionSystemException("UOWManager threw unexpected UOWActionException", ex);
|
||||
catch (UOWException | UOWActionException ex) {
|
||||
TransactionSystemException tse =
|
||||
new TransactionSystemException("UOWManager transaction processing failed", ex);
|
||||
Throwable appEx = action.getException();
|
||||
if (appEx != null) {
|
||||
logger.error("Application exception overridden by rollback exception", appEx);
|
||||
tse.initApplicationException(appEx);
|
||||
}
|
||||
throw tse;
|
||||
}
|
||||
finally {
|
||||
if (suspendedResources != null) {
|
||||
|
@ -368,12 +375,15 @@ public class WebSphereUowTransactionManager extends JtaTransactionManager
|
|||
}
|
||||
catch (Throwable ex) {
|
||||
this.exception = ex;
|
||||
if (status.isDebug()) {
|
||||
logger.debug("Rolling back on application exception from transaction callback", ex);
|
||||
}
|
||||
uowManager.setRollbackOnly();
|
||||
}
|
||||
finally {
|
||||
if (status.isLocalRollbackOnly()) {
|
||||
if (status.isDebug()) {
|
||||
logger.debug("Transactional code has requested rollback");
|
||||
logger.debug("Transaction callback has explicitly requested rollback");
|
||||
}
|
||||
uowManager.setRollbackOnly();
|
||||
}
|
||||
|
@ -396,6 +406,11 @@ public class WebSphereUowTransactionManager extends JtaTransactionManager
|
|||
return this.result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Throwable getException() {
|
||||
return this.exception;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRollbackOnly() {
|
||||
return obtainUOWManager().getRollbackOnly();
|
||||
|
|
|
@ -172,14 +172,10 @@ public class TransactionTemplate extends DefaultTransactionDefinition
|
|||
ex2.initApplicationException(ex);
|
||||
throw ex2;
|
||||
}
|
||||
catch (RuntimeException ex2) {
|
||||
catch (RuntimeException | Error ex2) {
|
||||
logger.error("Application exception overridden by rollback exception", ex);
|
||||
throw ex2;
|
||||
}
|
||||
catch (Error err) {
|
||||
logger.error("Application exception overridden by rollback error", ex);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue