/** * 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(); } } }