@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);
   }
 }