Browse Source

WebSphereUowTransactionManager logs overridden application exceptions

Issue: SPR-16102
pull/1576/head
Juergen Hoeller 7 years ago
parent
commit
efe943df72
  1. 54
      spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAspectSupport.java
  2. 33
      spring-tx/src/main/java/org/springframework/transaction/jta/WebSphereUowTransactionManager.java
  3. 6
      spring-tx/src/main/java/org/springframework/transaction/support/TransactionTemplate.java

54
spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAspectSupport.java

@ -306,6 +306,8 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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;
}

33
spring-tx/src/main/java/org/springframework/transaction/jta/WebSphereUowTransactionManager.java

@ -261,7 +261,8 @@ public class WebSphereUowTransactionManager extends JtaTransactionManager @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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();

6
spring-tx/src/main/java/org/springframework/transaction/support/TransactionTemplate.java

@ -172,14 +172,10 @@ public class TransactionTemplate extends DefaultTransactionDefinition @@ -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…
Cancel
Save