Мы используем Quartz для запуска пакетного процесса, который выполняет обновления данных нашего пользователя, а затем отправляет электронное письмо на основе определенного состояния учетной записи пользователя. Но мы не можем управлять сеансом гибернации за пределами зафиксированной транзакции, и мы получаем Hibernate LazyInitializationException
после того, как мы зафиксировали транзакцию и попытались получить доступ к отложенным объектам в нашей модели данных.
Как сохранить сеанс гибернации между несколькими транзакциями, чтобы мы могли продолжать получать доступ к отложенным объектам?
То, что мы хотим, это что-то вроде следующего потока кода:
- Кварц запускает наш процесс.
- Откройте новый сеанс с помощью спящего режима.
- Считать все записи, требующие обновления, из базы данных.
- Начать новую транзакцию с
@Transactional(propagation = Propagation.REQUIRES_NEW)
- Попытка обновить состояние учетной записи нашего пользователя.
- Совершить транзакцию.
- Если изменения состояния учетной записи пользователя отправляются пользователю по электронной почте с объяснением изменения состояния. Это то место, где выбрасывается
LazyInitializationException
.
- Полоскать, стирать, повторять, пока все пользовательские записи не будут обновлены.
Мы хотим следовать чему-то очень похожему на модель Spring OpenSessionInViewFilter
, но мы не можем правильно настроить наш код, и наша сессия всегда закрывается после первой @Transactional(propagation = Propagation.REQUIRES_NEW)
совершает.
Вопросы
Как нам настроить гибернацию на новые темы?
Что подводит меня ко второму вопросу:
Должны ли мы использовать класс Spring OpenSessionInViewInterceptor
для этой работы? Кажется, что это поведение, которое мы хотим, но это не совсем правильно.
Похоже, что SchedulerFactoryBean
имеет метод setTransactionManager(PlatformTransactionManager transactionManager)
, это тот метод, который используется для просто хранения Кварцевых триггеров в базе данных, или он используется для управления транзакциями, когда этот конкретный Кварцевая задача выполняется?
Вещи, которые мы пытались
Размещение @Transactional(propagation = Propagation.REQUIRED)
в начале нашей задачи Quartz, но транзакция не будет зафиксирована, пока все записи не будут обновлены. Таким образом, нашему пользователю были отправлены электронные письма, в которых сообщалось, что статус их учетной записи изменился, они проверят наш сайт до того, как транзакция подтвердит транзакцию, увидят старые данные своей учетной записи и будут сбиты с толку, потому что они видят старую информацию, и поэтому стало ясно, что " ... разработчики потеряли контроль над системой и не знают, что делают. "
Очень неловко, если не сказать больше.