code: protected <R> R getWithTransaction(TransactionalFunction<R> function) {
          Instant start = Instant.now();
          LazyToString callingMethod = getCallingMethod();
          logger.trace("{} : starting transaction", callingMethod);
  
          try(Connection tx = dataSource.getConnection()) {
              boolean previousAutoCommitMode = tx.getAutoCommit();
              tx.setAutoCommit(false);
              try {
                  R result = function.apply(tx);
                  tx.commit();
                  return result;
              } catch (Throwable th) {
                  tx.rollback();
                  throw new ApplicationException(ApplicationException.Code.BACKEND_ERROR, th.getMessage(), th);
              } finally {
                  tx.setAutoCommit(previousAutoCommitMode);
              }
          } catch (SQLException ex) {
              throw new ApplicationException(ApplicationException.Code.BACKEND_ERROR, ex.getMessage(), ex);
          } finally {
              logger.trace("{} : took {}ms", callingMethod, Duration.between(start, Instant.now()).toMillis());
          }
      }
docs: Initialize a new transactional {@link Connection} from {@link #dataSource} and pass it to {@literal function}.
  <p>
  Successful executions of {@literal function} will result in a commit and return of
  {@link TransactionalFunction#apply(Connection)}.
  <p>
  If any {@link Throwable} thrown from {@code TransactionalFunction#apply(Connection)} will result in a rollback
  of the transaction
  and will be wrapped in an {@link ApplicationException} if it is not already one.
  <p>
  Generally this is used to wrap multiple {@link #execute(Connection, String, ExecuteFunction)} or
  {@link #query(Connection, String, QueryFunction)} invocations that produce some expected return value.
  
  @param function The function to apply with a new transactional {@link Connection}
  @param <R>      The return type.
  @return The result of {@code TransactionalFunction#apply(Connection)}
  @throws ApplicationException If any errors occur.