示例#1
0
  /**
   * Run a block of code in a JPA transaction.
   *
   * @param name The persistence unit name
   * @param readOnly Is the transaction read-only?
   * @param block Block of code to execute
   */
  public <T> T withTransaction(String name, boolean readOnly, Supplier<T> block) {
    EntityManager entityManager = null;
    EntityTransaction tx = null;

    try {
      entityManager = em(name);

      if (entityManager == null) {
        throw new RuntimeException("No JPA entity manager defined for '" + name + "'");
      }

      JPA.bindForSync(entityManager);

      if (!readOnly) {
        tx = entityManager.getTransaction();
        tx.begin();
      }

      T result = block.get();

      if (tx != null) {
        if (tx.getRollbackOnly()) {
          tx.rollback();
        } else {
          tx.commit();
        }
      }

      return result;

    } catch (Throwable t) {
      if (tx != null) {
        try {
          tx.rollback();
        } catch (Throwable e) {
        }
      }
      throw t;
    } finally {
      JPA.bindForSync(null);
      if (entityManager != null) {
        entityManager.close();
      }
    }
  }