Ответ 1
withTransaction
немного хакерский, поскольку он позволяет выполнять транзакционную работу в любом месте, но лучше всего отделить свои проблемы и выполнить работу в транзакционной службе. Служба транзакционно по умолчанию, если вы не добавили static transactional = false
и можете быть точно настроены на уровне класса и/или метода с помощью аннотации @Transactional
. Вы должны просто помещать свой код в сервисный метод без использования withTransaction
или withSession
.
withSession
- это удобный способ доступа к текущему Hibernate Session
(обычно тот, который зарегистрирован перехватчиком OpenSessionInView). Если вы хотите очистить сеанс или выполнить другую работу, не отображаемую GORM, это способ получить к ней доступ, не обращаясь к sessionFactory
или локальным владельцам потоков, которые использует Spring.
Одним из действительных способов использования withTransaction
вне метода транзакционных сервисов является привязка Hibernate Session
, когда вы находитесь за пределами запроса контроллера (т.е. при отсутствии автоматического создания Session
). withTransaction
запустит транзакцию и при необходимости создаст Session
и сохранит ее на время закрытия. Поэтому вы можете использовать его, чтобы избежать исключений от ленивой загрузки. Нам нужен еще один способ сделать это без накладных расходов на транзакцию, в тех случаях, когда вы просто читаете из базы данных и не нуждаетесь в транзакционной записи. Но на данный момент этот подход работает. Однако, если вы делаете запись базы данных, переместите код в сервисный метод.