generified TransactionCallback; WebSphereUowTransactionManager preserves original exception in case of rollback (SPR-5270)

This commit is contained in:
Juergen Hoeller 2009-02-15 19:48:18 +00:00
parent d0b03604c8
commit a25e24f37e
5 changed files with 28 additions and 22 deletions

View File

@ -36,6 +36,7 @@ import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.DefaultTransactionStatus; import org.springframework.transaction.support.DefaultTransactionStatus;
import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionSynchronizationManager; import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.ReflectionUtils;
/** /**
* WebSphere-specific PlatformTransactionManager implementation that delegates * WebSphere-specific PlatformTransactionManager implementation that delegates
@ -62,11 +63,8 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
* despite the official WebSphere recommendations). Use the {@link #execute} style * despite the official WebSphere recommendations). Use the {@link #execute} style
* for any code that might require transaction suspension. * for any code that might require transaction suspension.
* *
* <p>This transaction manager is compatible with WebSphere 7.0 as well as recent * <p>This transaction manager is compatible with WebSphere 6.1.0.9 and above.
* WebSphere 6.0.x and 6.1.x versions. Check the documentation for your specific * The default JNDI location for the UOWManager is "java:comp/websphere/UOWManager".
* WebSphere version to find out whether UOWManager support is available.
*
* <p>The default JNDI location for the UOWManager is "java:comp/websphere/UOWManager".
* If the location happens to differ according to your WebSphere documentation, * If the location happens to differ according to your WebSphere documentation,
* simply specify the actual location through this transaction manager's * simply specify the actual location through this transaction manager's
* "uowManagerName" bean property. * "uowManagerName" bean property.
@ -191,7 +189,7 @@ public class WebSphereUowTransactionManager extends JtaTransactionManager
} }
public Object execute(TransactionDefinition definition, TransactionCallback callback) throws TransactionException { public <T> T execute(TransactionDefinition definition, TransactionCallback<T> callback) throws TransactionException {
if (definition == null) { if (definition == null) {
// Use defaults if no transaction definition given. // Use defaults if no transaction definition given.
definition = new DefaultTransactionDefinition(); definition = new DefaultTransactionDefinition();
@ -257,7 +255,7 @@ public class WebSphereUowTransactionManager extends JtaTransactionManager
if (debug) { if (debug) {
logger.debug("Invoking WebSphere UOW action: type=" + uowType + ", join=" + joinTx); logger.debug("Invoking WebSphere UOW action: type=" + uowType + ", join=" + joinTx);
} }
UOWActionAdapter action = new UOWActionAdapter( UOWActionAdapter<T> action = new UOWActionAdapter<T>(
definition, callback, (uowType == UOWManager.UOW_TYPE_GLOBAL_TRANSACTION), !joinTx, newSynch, debug); definition, callback, (uowType == UOWManager.UOW_TYPE_GLOBAL_TRANSACTION), !joinTx, newSynch, debug);
this.uowManager.runUnderUOW(uowType, joinTx, action); this.uowManager.runUnderUOW(uowType, joinTx, action);
if (debug) { if (debug) {
@ -282,11 +280,11 @@ public class WebSphereUowTransactionManager extends JtaTransactionManager
/** /**
* Adapter that executes the given Spring transaction within the WebSphere UOWAction shape. * Adapter that executes the given Spring transaction within the WebSphere UOWAction shape.
*/ */
private class UOWActionAdapter implements UOWAction { private class UOWActionAdapter<T> implements UOWAction {
private final TransactionDefinition definition; private final TransactionDefinition definition;
private final TransactionCallback callback; private final TransactionCallback<T> callback;
private final boolean actualTransaction; private final boolean actualTransaction;
@ -296,9 +294,11 @@ public class WebSphereUowTransactionManager extends JtaTransactionManager
private boolean debug; private boolean debug;
private Object result; private T result;
public UOWActionAdapter(TransactionDefinition definition, TransactionCallback callback, private Throwable exception;
public UOWActionAdapter(TransactionDefinition definition, TransactionCallback<T> callback,
boolean actualTransaction, boolean newTransaction, boolean newSynchronization, boolean debug) { boolean actualTransaction, boolean newTransaction, boolean newSynchronization, boolean debug) {
this.definition = definition; this.definition = definition;
this.callback = callback; this.callback = callback;
@ -316,6 +316,9 @@ public class WebSphereUowTransactionManager extends JtaTransactionManager
this.result = this.callback.doInTransaction(status); this.result = this.callback.doInTransaction(status);
triggerBeforeCommit(status); triggerBeforeCommit(status);
} }
catch (Throwable ex) {
this.exception = ex;
}
finally { finally {
if (status.isLocalRollbackOnly()) { if (status.isLocalRollbackOnly()) {
if (status.isDebug()) { if (status.isDebug()) {
@ -332,7 +335,10 @@ public class WebSphereUowTransactionManager extends JtaTransactionManager
} }
} }
public Object getResult() { public T getResult() {
if (this.exception != null) {
ReflectionUtils.rethrowRuntimeException(this.exception);
}
return this.result; return this.result;
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2007 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -53,7 +53,7 @@ public interface CallbackPreferringPlatformTransactionManager extends PlatformTr
* @throws TransactionException in case of initialization, rollback, or system errors * @throws TransactionException in case of initialization, rollback, or system errors
* @throws RuntimeException if thrown by the TransactionCallback * @throws RuntimeException if thrown by the TransactionCallback
*/ */
Object execute(TransactionDefinition definition, TransactionCallback callback) <T> T execute(TransactionDefinition definition, TransactionCallback<T> callback)
throws TransactionException; throws TransactionException;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2007 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -32,7 +32,7 @@ import org.springframework.transaction.TransactionStatus;
* @see TransactionTemplate * @see TransactionTemplate
* @see CallbackPreferringPlatformTransactionManager * @see CallbackPreferringPlatformTransactionManager
*/ */
public interface TransactionCallback { public interface TransactionCallback<T> {
/** /**
* Gets called by {@link TransactionTemplate#execute} within a transactional context. * Gets called by {@link TransactionTemplate#execute} within a transactional context.
@ -50,6 +50,6 @@ public interface TransactionCallback {
* @see TransactionTemplate#execute * @see TransactionTemplate#execute
* @see CallbackPreferringPlatformTransactionManager#execute * @see CallbackPreferringPlatformTransactionManager#execute
*/ */
Object doInTransaction(TransactionStatus status); T doInTransaction(TransactionStatus status);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2007 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -39,6 +39,6 @@ public interface TransactionOperations {
* @return a result object returned by the callback, or <code>null</code> if none * @return a result object returned by the callback, or <code>null</code> if none
* @throws TransactionException in case of initialization, rollback, or system errors * @throws TransactionException in case of initialization, rollback, or system errors
*/ */
Object execute(TransactionCallback action) throws TransactionException; <T> T execute(TransactionCallback<T> action) throws TransactionException;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2007 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -117,13 +117,13 @@ public class TransactionTemplate extends DefaultTransactionDefinition
} }
public Object execute(TransactionCallback action) throws TransactionException { public <T> T execute(TransactionCallback<T> action) throws TransactionException {
if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) { if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) {
return ((CallbackPreferringPlatformTransactionManager) this.transactionManager).execute(this, action); return ((CallbackPreferringPlatformTransactionManager) this.transactionManager).execute(this, action);
} }
else { else {
TransactionStatus status = this.transactionManager.getTransaction(this); TransactionStatus status = this.transactionManager.getTransaction(this);
Object result = null; T result = null;
try { try {
result = action.doInTransaction(status); result = action.doInTransaction(status);
} }