Методы @Transactional в классе @Controller не рассматриваются как транзакционные
Я заметил, что следующее не работает в классе, помеченном как @Controller
:
@Autowired
SessionFactory sessionFactory;
@ResponseBody
@Transactional
@RequestMapping(method = RequestMethod.GET , value = "/map")
public ArrayList<PhotoDTO> getPhotos(...someParams) {
Entity result sessionFactory.getCurrentSession()... //do some manipulation
return result;
}
когда я вызываю URL-адрес, я получаю сообщение о том, что метод не является транзакционным (хотя, как видите, он помечен как один)
Если я скопирую этот метод в другой класс под названием MyService и вызову его из контроллера, он отлично работает
Это какой-то совет Spring (заговор, чтобы заставить меня использовать больше классов более или менее)?
Ответы
Ответ 1
Не делайте транзакций в своем контроллере. Поместите их в классы уровня обслуживания.
Отделите свой код в контроллере модели.
Да, это заговор. Он позволяет вам совместно использовать код между контроллерами/представлениями без повторения кода. А также отменяет откаты транзакций без необходимости (для исключений, не связанных с фактической транзакцией).
Может показаться, что для начала потребуется больше кода, но в долгосрочной перспективе он намного более управляем и проще разрабатывается.
Ответ 2
Вероятно, здесь есть два контекста приложения: основной Spring контекст, загруженный ContextLoaderListener
, и дочерний контекст, загруженный DispatcherServlet
. Вы должны поместить <tx:annotation-driven />
в конфигурацию, загруженную детским контекстом. Если вы покажете нам свой файл web.xml
, я могу помочь вам больше.
В любом случае, как говорит @NimChimpsky, обычно не является хорошей практикой для управления транзакциями на вашем уровне контроллера.