Как управляются соединения с базой данных для репозиториев Spring Data JPA? - PullRequest
0 голосов
/ 29 августа 2018

У меня вопрос о том, как репозитории Spring Data обрабатывают соединения с источником данных. Предполагая, что репозитории Spring Data открывают и закрывают соединение и соединение при выполнении метода, как транзакция началась с объявления @Transactional в моем слое уровня обслуживания между несколькими вызовами из репозитория?

Кто обрабатывает соединения с базой данных? @Transactional аннотация или репозиторий JPA?

1 Ответ

0 голосов
/ 30 августа 2018

ТЛ; др

В конечном счете, это инфраструктура 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, доступной для рендеринга представления, но сохраняет соединение открытым дольше, чем если бы это было необходимо только для фактической транзакционной работы.

Эта тема весьма спорная , так как она представляет собой хитрый баланс между удобством разработчика (возможность лениво перебирать объектные отношения, загруженные в фазе рендеринга представления) с риском именно того, что вызывает дорогостоящие дополнительные запросы и сохранение ресурсов в течение более длительного времени.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...