Эта статья проведет подробные исследования по управлению транзакциями весны. В основном представляет, как работает @Transactional внизу. В следующей статье будет представлена:
Использование таких атрибутов, как распространение (распространение транзакций) и изоляция (изоляция)
Каковы подводные камни использования транзакций и как его избежать
JPA и управление транзакциями
Важно, чтобы сам JPA не обеспечивал какого -либо декларативного управления транзакциями. Если вы используете JPA за пределами контейнера впрыскивания зависимостей, транзакция должна быть реализована программно разработчиком.
Usertransaction utx = entitymanager.gettransaction (); try {utx.begin (); businesslogic (); utx.commit ();} catch (exception ex) {utx.rollback (); throwex;}Этот способ управления транзакциями позволяет четко выражать сферу транзакций в коде, но у него есть следующие недостатки:
Повторный код и ошибки подвержены
Любые ошибки могут оказать большее влияние
Ошибки трудно отлаживать и воспроизводить
Уменьшает читаемость кодовой базы
Что если метод вызывает другие методы транзакции?
Используя Spring @Transactional
Используя Spring @Transactional, приведенный выше код упрощен:
@Transactional publicvoid businesslogic () {... Используйте менеджер объектов внутри транзакции ...}Код более краткий и читаемый, и это также рекомендуемый способ разобраться весной в настоящее время.
Многие важные аспекты, такие как распространение транзакций, могут быть обработаны автоматически с помощью @Transactional. В этом случае, если BusinessLogic () вызывает другой метод транзакции, метод будет определять, как присоединиться к запущенной транзакции на основе параметров.
Одним из потенциальных недостатков этого мощного механизма является то, что он скрывает основную операцию и трудно отлаживать, когда он не работает должным образом.
@Transactional
Одним из ключевых моментов о @Transactional является рассмотрение двух отдельных концепций, оба из которых имеют свой собственный объем и жизненный цикл:
контекст настойчивости (контекст настойчивости)
Транзакция базы данных
@Transactional сам определяет область одной транзакции. Эта транзакция находится в рамках контекста постоянства.
Контекст устойчивости в JPA является EntityManager, и внутренняя реализация использует сеанс Hibernate (используя Hibernate в качестве поставщика постоянств).
Контекст постоянства - это просто синхронный объект, который записывает состояние Java -объектов конечной коллекции и гарантирует, что изменения в этих объектах в конечном итоге сохраняются в базе данных.
Это совсем другая концепция от одной транзакции. Диспетчер сущностей может использоваться во всех транзакциях, и он действительно используется таким образом.
Когда EntityManager охватывает несколько транзакций?
Наиболее распространенная ситуация - это когда приложение использует открытый сеанс в режиме просмотра для обработки ленивых исключений инициализации. Предыдущие статьи представили преимущества и недостатки этого подхода.
В этом случае несколько запросов, выполняемых по уровню представления, находятся в отдельных транзакциях, а не в бизнес -логике с одной транзакцией, но эти запросы управляются одним и тем же менеджером объектов.
Другой сценарий заключается в том, что разработчик отмечает контекст настойчивости как PersistenceContextType.extended, что означает, что он может отвечать на несколько запросов.
Как определить взаимосвязь между EntityManager и транзакцией?
Это выбирается разработчиками приложений, но наиболее распространенным способом для менеджера объектов JPA является режим «Диспетчер объектов на транзакцию приложения». Общие методы инъекции менеджера сущности:
@Persistencecontext pretatentitymanager em;
По умолчанию режим «Диспетчер объектов на транзакцию». В этом режиме, если менеджер объектов используется внутри метода @Transactional, метод будет работать в одной транзакции.
Как работает @persistencecontext?
Вопрос, который следует, заключается в том, как @persistencecontext может вводить менеджер объектов только тогда, когда начинается контейнер, предполагая, что жизненный цикл менеджера объектов является коротким и требует нескольких менеджеров объектов по запросу.
Ответ заключается в том, что он не может: EntityManager - это интерфейс, и то, что вводится в пружинный фасоль, является не самого менеджера объектов, а контекстный прокси (контекстный прокси) конкретного менеджера объектов во время выполнения.
Конкретный класс, обычно используемый для Proxy, является ShareDentityManagerInvocationHandler, который может быть подтвержден с помощью отладчика.
Так как же работает @Transactional?
Постоянный контекстный прокси, который реализует интерфейс EntityManager, является не единственной частью декларативного управления транзакциями, но на самом деле содержит три компонента:
EntityManager Shere Proxy
Раздел транзакции
Менеджер транзакций
Взгляните на эти три части и их взаимодействие.
Раздел транзакции
Раздел транзакций представляет собой раздел «вокруг», который можно вызвать до и после аннотированного бизнес -метода. Конкретный класс, который реализует раздел, является TransactionInterceptor.
В разделе транзакции есть две основные обязанности:
В «До» раздел предоставляет точку вызова, чтобы решить, должен ли вызывный бизнес -метод работать в рамках продолжающейся транзакции или запустить новую независимую транзакцию.
В «после» раздел должен определить, что транзакция совершается, откатится или продолжала работать.
В «До» сама раздел транзакций не содержит никакой логики принятия решений, и решение о начале новой транзакции делегируется менеджеру транзакций для завершения.
Менеджер транзакций
Менеджер транзакций должен решить следующие две задачи:
Следует ли создать новый менеджер сущностей?
Следует ли начать новую транзакцию?
Они требуют, чтобы разделы транзакций были определены при вызываемой логике «до». Решения менеджера транзакций основаны на следующих двух пунктах:
Проходит транзакция
Свойство распространения метода транзакции (например, требуется_new всегда начинает новую транзакцию)
Если менеджер транзакций определит, что вы хотите создать новую транзакцию, это будет:
1. Создайте нового менеджера объектов
2. Диспетчер наетки связан с текущим потоком
3. Получить соединение из пула соединений базы данных
4. Приведите соединение с текущим потоком
Используйте потоковую переменную, чтобы связать как диспетчер объектов, так и подключение к базе данных с текущим потоком.
Транзакции работают, когда они хранятся в потоке, и когда они больше не используются, менеджер транзакций решает, очистить ли их.
Любая часть программы может быть извлечена из потока, если требуется текущий диспетчер объектов и подключение к базе данных.
EntityManager Proxy
EntityManager Proxy (уже представлен ранее) является последней частью головоломки. Когда бизнес -метод вызывает EntityManager.persist (), это не называется непосредственно менеджером объектов.
Вместо этого бизнес -метод вызывает агента, который получает текущего менеджера объектов из потока. Как упоминалось ранее, менеджер транзакций связывает менеджер объектов с потоком.
Понимая различные части механизма @Transactional, давайте посмотрим на обще используемые пружинные конфигурации, которые его реализуют.
Интегрируйте три части
Как объединить три части, чтобы аннотации транзакций могли работать правильно? Сначала определите фабрику менеджера сущности.
Это позволяет вам внедрить прокси -контекстный контекстный контекст.
@Configuration publicclass entitymanagerfactoryconfiguration {@autowired privatedatasource DataSource; @bean (name = "EntityManagerFactory") publiclocalContainerentItymanagerFactoryBean EMF () {LocalContaInerentityManagerfactoryBeanbeanbenaCace (dataSourceSepeC.SeteCaseCeSace); Newstring [] {"your.package"}); emf.setJpavendorAdapter (newhibernateJpavendorAdapter ()); returnemf;}}Следующим шагом является настройка диспетчера транзакций и применение аспектов транзакций в классе, аннотированных @Transactional.
@Configuration @enabletransactionmanagement publicclass transactionmanagersconfig {@autowired entitymanagerfactory emf; @autowired privatedatasource dataSource; @Bean (name = "transactionManager") newjpatransactionmanager (); tm.setentitymanagerfactory (emf); tm.setdatasource (dataSource); returnm;}}Аннотация @enableTransactionManagement уведомляет пружину, что класс, аннотированный @Transactional, окружен вырезанной транзакцией. Таким образом, @transactional можно использовать.
Суммировать
Декларативный механизм управления транзакциями Spring очень мощный, но его можно неправильно использовать или легко настроить ошибки.
Когда такие проблемы, как этот механизм, не работают должным образом или не достигают ожидаемых операционных результатов, полезно понять его внутреннюю работу.
Самое важное, что нужно помнить, - это учитывать две концепции: транзакции и контексты настойчивости, каждая из которых со своим очевидным жизненным циклом, который является нечитаемым.
Выше приведено все содержание этой статьи о принципе работы Spring @Transactional. Я надеюсь, что это будет полезно для всех. Заинтересованные друзья могут продолжать ссылаться на другие связанные темы на этом сайте. Если есть какие -либо недостатки, пожалуйста, оставьте сообщение, чтобы указать это. Спасибо, друзья, за вашу поддержку на этом сайте!