Ну, я бы сказал, что вы перечислили все возможные варианты, кроме OpenSessionInView . Это поддержит ваш сеанс между транзакциями, но это трудно реализовать должным образом. Так сложно, что его считают AntiPattern многими .
Однако, поскольку вы не реализуете веб-интерфейс и не имеете дело с многопоточной средой, я бы сказал, что это путь. Это не значит, что вы передаете сущности представлениям. Вы больше всего боитесь вызова N + 1 в базу данных при выполнении итерации по коллекции, но, поскольку это задача cron, производительность может не быть серьезной проблемой по сравнению с чистотой кода. Если вы действительно обеспокоены этим, просто убедитесь, что вы получили все свои коллекции, позвонив в DAO, который может сделать выбор *.
Кроме того, вы эффективно делали Open Session In View раньше, когда вы делали все в одной транзакции. Весной сеансы открываются на основе каждой транзакции, поэтому поддержание транзакции открытой в течение длительного периода времени практически равнозначно хранению сессии в течение длительного периода времени. Единственной реальной разницей в вашем случае будет тот факт, что вы можете периодически совершать операции, не опасаясь ленивой ошибки инициализации в будущем.
Редактировать
С учетом всего вышесказанного требуется немного времени для настройки открытого сеанса в представлении, поэтому, если у вас нет особых проблем с выполнением всего в одной транзакции, вы можете рассмотреть возможность просто вернуться к этому.
Кроме того, я только что заметил, что вы упомянули об открытии транзакции в пакетном слое, а затем об открытии «мини транзакций» в сервисном слое. Это совершенно НЕ хорошая идея. Транзакции Spring, управляемые аннотациями, будут привязаны к любой открытой в данный момент транзакции в сеансе. Это означает, что транзакции, которые должны быть доступны только для чтения, внезапно станут доступными для чтения и записи, если открытая в настоящее время транзакция предназначена для чтения и записи. Кроме того, сеанс не будет сброшен до тех пор, пока внешняя транзакция в любом случае не будет завершена, поэтому нет смысла отмечать слой Service с помощью @Transactional
. Помещение @Transactional
на несколько слоев создает ложное чувство безопасности.
Я на самом деле писал об этой проблеме некоторое время назад.