@Override public synchronized <T> T execute(Command<T> command) { boolean transactionOwner = false; T result = null; try { transactionOwner = txm.begin(); tpm.beginCommandScopedEntityManager(); TransactionManagerHelper.registerTransactionSyncInContainer( this.txm, new TaskSynchronizationImpl(this)); result = executeNext((Command<T>) command); postInit(result); txm.commit(transactionOwner); return result; } catch (TaskException e) { // allow to handle TaskException as business exceptions on caller side // if transaction is owned by other component like process engine if (transactionOwner) { rollbackTransaction(e, transactionOwner); e.setRecoverable(false); throw e; } else { throw e; } } catch (RuntimeException re) { rollbackTransaction(re, transactionOwner); throw re; } catch (Exception t1) { rollbackTransaction(t1, transactionOwner); throw new RuntimeException("Wrapped exception see cause", t1); } }
private void rollbackTransaction(Exception t1, boolean transactionOwner) { try { logger.warn("Could not commit session", t1); txm.rollback(transactionOwner); } catch (Exception t2) { logger.error("Could not rollback", t2); throw new RuntimeException("Could not commit session or rollback", t2); } }