∫created

Integration created

How to hide transaction implementation

TL;DR

Every transaction in Idempiere is implemented with Transaction initialization and finalisation. Here is example of transaction implementation:

		String trxName = null;
		Trx trx = null;
		try {
			trxName = Trx.createTrxName("AwesomeOrderTransaction");
			trx = Trx.get(trxName, true);

            MOrder order = new MOrder(Env.getCtx(), orderId, trxName);
            // Do something amazing with order
            order.save(trxName);

		} catch (Exception e) {
			if (trx != null) {
				trx.rollback();
				trx.close();
				trx = null;
			}
			throw new AdempiereException(e);
		} finally {
			if (trx != null) {
				trx.commit();
				trx.close();
			}
		}

Desired implementation

It is a good practice to hide transaction implementation from the client code. It will help you to avoid code duplication and make your code more readable. Here is how we would like to see our code:

        MOrder createdOrder = Transaction.run((trxName) -> {
            MOrder order = new MOrder(ctx, orderId, trxName);
            // Do something amazing with order
            order.save(trxName);
            return order;
        });

Implementation

Here is the implementation of the Transaction class:

  public static <T> T run(Function<String, T> transaction) {

    Trx trx = null;
    try {
      String transactionName = Thread.currentThread().getStackTrace()[2].getMethodName();
      String trxName = Trx.createTrxName(transactionName);
      trx = Trx.get(trxName, true);
      T object = transaction.apply(trxName);
      if (trx.commit()) {
        return object;
      }

    } catch (Throwable e) {
      if (trx != null) {
        trx.rollback();
        trx.close();
        trx = null;
      }
    } finally {
      if (trx != null) {
        trx.close();
      }
    }
    return null;
  }

Note that we use Thread.currentThread().getStackTrace()[2].getMethodName() to get the name of the method that calls Transaction.run(). It is a good practice to use the name of the method as a transaction name. It will help you to find the transaction in the log file.

Conclusion

This lambda approach can be used for JDBC implementation too like here: How to hide JDBC implementation