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); + } + } + } + } } |
Free forum by Nabble | Edit this page |