ТЛ; др
В конечном счете, это инфраструктура Spring JPA / Transaction, управляющая соединением с помощью управления привязкой к объекту EntityManager
. Объем транзакции контролируется аннотациями @Transactional
в пользовательском коде, но в конечном итоге по умолчанию используется в репозитории Spring Data JPA. Получение соединения выполняется с нетерпением, если используется OpenEntityManagerInViewFilter
(по умолчанию включено в Spring Boot 1.x и 2.x).
Подробнее
SimpleJpaRepository
оснащен аннотациями Spring @Transactional
, поэтому он будет обеспечивать выполнение транзакций в тех случаях, когда этого требует JPA (например, для выполнения вызова на EntityManager.persist(…)
или ….merge(…)
). Их конфигурация по умолчанию гарантирует, что они автоматически принимают участие в транзакциях, запущенных на более высоких уровнях абстракции. То есть если у вас есть компонент Spring, который сам по себе @Transactional
, репозитории просто будут участвовать в уже запущенной транзакции:
@Component
class MyService {
private final FirstRepository first;
private final SecondRepository second;
// Constructor omitted for brevity
@Transactional
void someMethod() {
… = first.save(…);
… = second.save(…);
}
}
Оба хранилища участвуют в транзакции, и сбой в одном из них откатит всю транзакцию.
Для этого JpaTransactionManager
будет использовать API управления транзакциями, предоставляемый JPA EntityManager
, для запуска транзакции и установления соединения на время существования экземпляра EntityManager
. Подробнее см. JpaTransactionManager.doBegin(…)
.
Роль OpenEntityManagerInViewFilter
или –Interceptor
Если явно не отключена, веб-приложения Spring Boot 1.x и 2.x запускаются с развернутым OpenEntityManagerInViewFilter
. Он используется для создания EntityManager
и, таким образом, довольно рано получает соединение и сохраняет его до очень позднего периода обработки запроса, а именно после представления представления. Это имеет эффект отложенной загрузки JPA, доступной для рендеринга представления, но сохраняет соединение открытым дольше, чем если бы это было необходимо только для фактической транзакционной работы.
Эта тема весьма спорная , так как она представляет собой хитрый баланс между удобством разработчика (возможность лениво перебирать объектные отношения, загруженные в фазе рендеринга представления) с риском именно того, что вызывает дорогостоящие дополнительные запросы и сохранение ресурсов в течение более длительного времени.