От Профессиональная Java для веб-приложений. Николас С. Уильямс
Область транзакции в Spring ограничена потоком, в котором начинается транзакция. Затем менеджер транзакций связывает транзакцию с управляемыми ресурсами, используемыми в том же потоке в течение срока действия транзакции. При использовании API Java Persistence ресурс, с которым вы работаете, - EntityManager
. Это функциональный эквивалент сеанса Hibernate ORM и соединения JDBC. Обычно вы получаете EntityManager
от EntityManagerFactory
до начала транзакции и выполнения действий JPA. Однако это не работает с моделью Spring Framework для управления транзакциями от вашего имени. Решением этой проблемы является org.springframework.orm.jpa.support.SharedEntityManagerBean
. Когда вы конфигурируете JPA в Spring Framework, он создает SharedEntityManagerBean
, который проксирует интерфейс EntityManager
. Затем этот прокси вводится в ваши репозитории JPA. Когда метод EntityManager
вызывается для этого экземпляра прокси, в фоновом режиме происходит следующее:
➤➤ Если текущий поток уже имеет действительную EntityManager
с активной транзакцией, он делегирует вызов этому методу EntityManager
.
➤➤ В противном случае Spring Framework получает новый EntityManager
из EntityManagerFactory
, запускает транзакцию и связывает оба с текущим потоком. Затем он делегирует вызов этому методу EntityManager
. Когда транзакция либо фиксируется, либо откатывается, Spring отменяет привязку транзакции и EntityManager
из потока, а затем закрывает EntityManager
. Будущие действия @Transactional
в том же потоке (даже в пределах одного и того же запроса) запускают процесс заново, получая новый EntityManager
с завода и начиная новую транзакцию. Таким образом, нет двух потоков, использующих EntityManager
одновременно, и данный поток имеет только одну транзакцию и одну EntityManager
активную в любой момент времени.
Если бы вы использовали , а не , чтобы использовать Spring MVC, то вы бы получили сеанс, используя SessionFactory
в Hibernate. Сеансы гибернации представляют жизнь транзакции от начала до конца. В зависимости от того, как разработано ваше приложение, это может занять не более секунды или нескольких минут; и в веб-приложении это может быть одна из нескольких транзакций в запросе, транзакция, длящаяся весь запрос, или транзакция, охватывающая несколько запросов. Session
, который не является потокобезопасным и должен использоваться только в одном потоке за раз, отвечает за управление состоянием объектов.