code: protected void fireTransactionEvent(TransactionState transactionState, boolean executeInNewContext) {
      if (stateTransactionListeners==null) {
        return;
      }
      final List<TransactionListener> transactionListeners = stateTransactionListeners.get(transactionState);
      if (transactionListeners==null) {
        return;
      }
      
      if (executeInNewContext) {
        CommandExecutor commandExecutor = commandContext.getProcessEngineConfiguration().getCommandExecutor(); 
        CommandConfig commandConfig = new CommandConfig(false, TransactionPropagation.REQUIRES_NEW); 
        commandExecutor.execute(commandConfig, new Command<Void>() {
          public Void execute(CommandContext commandContext) {
            executeTransactionListeners(transactionListeners, commandContext);
            return null;
          }
        });
      } else {
        executeTransactionListeners(transactionListeners, commandContext);
      }
      
    }
docs: Fires the event for the provided {@link TransactionState}.
  
  @param transactionState The {@link TransactionState} for which the listeners will be called.
  @param executeInNewContext If true, the listeners will be called in a new command context.
  This is needed for example when firing the {@link TransactionState#COMMITTED}
  event: the transacation is already committed and executing logic in the same
  context could lead to strange behaviour (for example doing a {@link SqlSession#update(String)}
  would actually roll back the update (as the MyBatis context is already committed
  and the internal flags have not been correctly set).