Как в Hibernate/JPA задать уровень изоляции транзакции?

«Как в Hibernate/JPA задать уровень изоляции транзакции?» — вопрос из категории Hibernate, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Hibernate, как реализация JPA, не управляет уровнями изоляции напрямую — это ответственность базы данных. Однако он позволяет декларировать требуемый уровень, который будет использован при создании JDBC-соединения.

Способы задания уровня изоляции:

  1. Через аннотацию @Transactional (Spring):

    import org.springframework.transaction.annotation.Isolation;
    import org.springframework.transaction.annotation.Transactional;
    
    @Service
    public class UserService {
    
        @Transactional(isolation = Isolation.READ_COMMITTED)
        public void updateUser(Long id) {
            // ... логика
        }
    }
  2. В настройках persistence.xml (JPA):

    <property name="javax.persistence.lock.timeout" value="10000"/>
    <!-- Или специфичные для Hibernate -->
    <property name="hibernate.connection.isolation" value="2"/>
    <!-- 2 = Connection.TRANSACTION_READ_COMMITTED -->

Стандартные уровни изоляции (enum Isolation):

  • READ_UNCOMMITTED – Чтение незафиксированных данных.
  • READ_COMMITTED – Чтение только зафиксированных данных (по умолчанию в многих СУБД).
  • REPEATABLE_READ – Гарантирует повторяемость чтения.
  • SERIALIZABLE – Полная изоляция, строгая последовательность.

Важно: Поддержка конкретных уровней и их семантика зависят от СУБД (MySQL, PostgreSQL и т.д.). Указание неподдерживаемого уровня может быть проигнорировано или привести к ошибке.