JPA Transactions

Basic Java
≈ 1 min read

Entity changes need clear transaction boundaries

A persistence context tracks object changes, but business operations still need transaction boundaries. A transaction defines which changes must be committed together and which must be rolled back if an error occurs.

A resource-local transaction with EntityTransaction

EntityTransaction tx = entityManager.getTransaction();

tx.begin();
try {
    User user = entityManager.find(User.class, 42L);
    user.setActive(true);
    tx.commit();
} catch (RuntimeException e) {
    if (tx.isActive()) {
        tx.rollback();
    }
    throw e;
}

After begin(), changes to managed Entities become part of the current transactional work. commit() completes it successfully, while rollback() cancels the transaction changes when an error occurs.

commit and flush are not the same thing

Before commit, the provider must synchronize the necessary persistence-context changes with the database. But the fact that SQL has executed does not itself mean commit: the transaction can still be rolled back later. It is therefore important to distinguish state synchronization from final transaction completion.

Transaction boundaries should match the business operation. If several changes must either all succeed or all fail, they should not accidentally be split across independent transactions.