Транзакции JPA

Базовый Java
≈ 1 мин чтения

Изменения Entity должны происходить в понятных границах транзакции

Persistence context отслеживает изменения объектов, но бизнес-операции всё равно требуют транзакционных границ. Транзакция определяет, какие изменения должны быть зафиксированы вместе, а какие нужно откатить при ошибке.

Resource-local транзакция через 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;
}

После begin() изменения managed-Entity входят в текущую транзакционную работу. commit() завершает её успешно, а rollback() отменяет изменения транзакции при ошибке.

commit и flush — не одно и то же

Перед фиксацией provider должен синхронизировать необходимые изменения persistence context с базой. Но сам факт выполнения SQL ещё не означает commit: транзакция может быть откатана позже. Поэтому важно разделять синхронизацию состояния и окончательное подтверждение транзакции.

Границы транзакции должны соответствовать бизнес-операции. Если несколько изменений должны либо выполниться все, либо не выполниться вовсе, их нельзя случайно разносить по независимым транзакциям.