You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by do...@apache.org on 2011/06/30 00:11:54 UTC
svn commit: r1141282 -
/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/transaction/TransactionUtil.java
Author: doogie
Date: Wed Jun 29 22:11:54 2011
New Revision: 1141282
URL: http://svn.apache.org/viewvc?rev=1141282&view=rev
Log:
FEATURE: Reworked Callable helper methods to support wrapping/proxying, so
that calling code can pass the reconstructed objects directly to
Executor instances.
As a nice side effect, these classes show up in exceptions, so you can
know a bit more about the transaction nature of the call stack.
Modified:
ofbiz/trunk/framework/entity/src/org/ofbiz/entity/transaction/TransactionUtil.java
Modified: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/transaction/TransactionUtil.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/transaction/TransactionUtil.java?rev=1141282&r1=1141281&r2=1141282&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/transaction/TransactionUtil.java (original)
+++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/transaction/TransactionUtil.java Wed Jun 29 22:11:54 2011
@@ -76,53 +76,33 @@ public class TransactionUtil implements
private static ThreadLocal<Timestamp> transactionLastNowStamp = new ThreadLocal<Timestamp>();
public static <V> V doNewTransaction(String ifErrorMessage, Callable<V> callable) throws GenericEntityException {
- return doNewTransaction(ifErrorMessage, true, callable);
+ return inTransaction(noTransaction(callable), ifErrorMessage, 0, true).call();
}
public static <V> V doNewTransaction(String ifErrorMessage, boolean printException, Callable<V> callable) throws GenericEntityException {
- Transaction tx = TransactionUtil.suspend();
- try {
- return doTransaction(ifErrorMessage, printException, callable);
- } finally {
- TransactionUtil.resume(tx);
- }
+ return inTransaction(noTransaction(callable), ifErrorMessage, 0, printException).call();
}
public static <V> V doTransaction(String ifErrorMessage, Callable<V> callable) throws GenericEntityException {
- return doTransaction(ifErrorMessage, true, callable);
+ return inTransaction(callable, ifErrorMessage, 0, true).call();
}
public static <V> V doTransaction(String ifErrorMessage, boolean printException, Callable<V> callable) throws GenericEntityException {
- boolean tx = TransactionUtil.begin();
- Throwable transactionAbortCause = null;
- try {
- try {
- return callable.call();
- } catch (Throwable t) {
- while (t.getCause() != null) {
- t = t.getCause();
- }
- throw t;
- }
- } catch (Error e) {
- transactionAbortCause = e;
- throw e;
- } catch (RuntimeException e) {
- transactionAbortCause = e;
- throw e;
- } catch (Throwable t) {
- transactionAbortCause = t;
- throw new GenericEntityException(t);
- } finally {
- if (transactionAbortCause == null) {
- TransactionUtil.commit(tx);
- } else {
- if (printException) {
- transactionAbortCause.printStackTrace();
- }
- TransactionUtil.rollback(tx, ifErrorMessage, transactionAbortCause);
- }
- }
+ return inTransaction(callable, ifErrorMessage, 0, printException).call();
+ }
+
+ public static <V> Callable<V> noTransaction(Callable<V> callable) {
+ return new NoTransaction<V>(callable);
+ }
+
+ // This syntax is groovy compatible, with the primary(callable) as the first arg.
+ // You could do:
+ // use (TransactionUtil) {
+ // Callable callable = ....
+ // Object result = callable.noTransaction().inTransaction(ifError, timeout, print).call()
+ // }
+ public static <V> InTransaction<V> inTransaction(Callable<V> callable, String ifErrorMessage, int timeout, boolean printException) {
+ return new InTransaction<V>(callable, ifErrorMessage, timeout, printException);
}
/** Begins a transaction in the current thread IF transactions are available; only
@@ -972,4 +952,68 @@ public class TransactionUtil implements
public void beforeCompletion() {
}
}
+
+ public static final class NoTransaction<V> implements Callable<V> {
+ private final Callable<V> callable;
+
+ protected NoTransaction(Callable<V> callable) {
+ this.callable = callable;
+ }
+
+ public V call() throws Exception {
+ Transaction suspended = TransactionUtil.suspend();
+ try {
+ return callable.call();
+ } finally {
+ TransactionUtil.resume(suspended);
+ }
+ }
+ }
+
+ public static final class InTransaction<V> implements Callable<V> {
+ private final Callable<V> callable;
+ private final String ifErrorMessage;
+ private final int timeout;
+ private final boolean printException;
+
+ protected InTransaction(Callable<V> callable, String ifErrorMessage, int timeout, boolean printException) {
+ this.callable = callable;
+ this.ifErrorMessage = ifErrorMessage;
+ this.timeout = timeout;
+ this.printException = printException;
+ }
+
+ public V call() throws GenericEntityException {
+ boolean tx = TransactionUtil.begin(timeout);
+ Throwable transactionAbortCause = null;
+ try {
+ try {
+ return callable.call();
+ } catch (Throwable t) {
+ while (t.getCause() != null) {
+ t = t.getCause();
+ }
+ throw t;
+ }
+ } catch (Error e) {
+ transactionAbortCause = e;
+ throw e;
+ } catch (RuntimeException e) {
+ transactionAbortCause = e;
+ throw e;
+ } catch (Throwable t) {
+ transactionAbortCause = t;
+ throw new GenericEntityException(t);
+ } finally {
+ if (transactionAbortCause == null) {
+ TransactionUtil.commit(tx);
+ } else {
+ if (printException) {
+ transactionAbortCause.printStackTrace();
+ }
+ TransactionUtil.rollback(tx, ifErrorMessage, transactionAbortCause);
+ }
+ }
+ }
+ }
}