Skip to content

20 Как «под капотом» работает @Transactional?

Аннотация @Transactional в Spring (и других фреймворках) используется для управления транзакциями в приложениях. Она позволяет разработчикам легко определять границы транзакций, не заботясь о низкоуровневых деталях управления транзакциями. Рассмотрим, как это работает «под капотом».

Основные аспекты работы @Transactional:

  1. Прокси-объекты:
  2. Spring создает прокси-объект для класса, помеченного аннотацией @Transactional. Это может быть либо JDK-динамический прокси (если класс реализует интерфейсы), либо CGLIB-прокси (если класс не реализует интерфейсы).
  3. Прокси-объект перехватывает вызовы методов и добавляет логику управления транзакциями.

  4. Аспектно-ориентированное программирование (AOP):

  5. Spring использует AOP для внедрения поведения транзакций. При вызове метода прокси-объект сначала открывает транзакцию, затем вызывает целевой метод, и, в зависимости от результата, либо фиксирует транзакцию (commit), либо откатывает её (rollback) в случае исключения.

  6. Управление транзакциями:

  7. Spring использует PlatformTransactionManager для управления транзакциями. В зависимости от конфигурации (например, JDBC, JPA, Hibernate) используется соответствующий менеджер транзакций.
  8. При открытии транзакции создается контекст транзакции, который отслеживает изменения и состояние.

  9. Изоляция и уровень изоляции:

  10. @Transactional позволяет задавать уровень изоляции и другие параметры транзакции, такие как propagation, timeout, readOnly и т.д. Эти параметры определяют, как транзакция будет взаимодействовать с другими транзакциями.

  11. Обработка исключений:

  12. По умолчанию Spring откатывает транзакцию при возникновении непроверяемых исключений (например, RuntimeException). Проверяемые исключения (например, SQLException) не приводят к откату, если не указано иное.

Пример использования:

@Service
public class UserService {

    @Transactional
    public void createUser(User user) {
        userRepository.save(user);
        // Другие операции, которые должны быть в одной транзакции
    }
}

В этом примере, когда метод createUser вызывается, Spring открывает транзакцию, выполняет сохранение пользователя и, если все проходит успешно, фиксирует транзакцию. Если возникает исключение, транзакция будет откатана.

Заключение:

Аннотация @Transactional значительно упрощает управление транзакциями, позволяя разработчикам сосредоточиться на бизнес-логике, а не на низкоуровневых деталях работы с транзакциями.