Поведение Spring при распространении транзакций на практике

Spring
Поведение Spring при распространении транзакций на практике

Поведение Spring при распространении транзакций на практике

Обзор

Платформа Spring обеспечивает стандартную реализацию управления транзакциями, а транзакции можно объявлять и настраивать с помощью аннотаций или XML-файлов.

Разделение вызовов службы через асинхронные события может повысить скорость отклика программы и избежать проблем с транзакциями, вызванных поведением распространения транзакций.

В этой статье задача переноса библиотеки из платформы электронной коммерции в качестве фактического фона, разделения вложенных транзакций с помощью асинхронных событий и пулов потоков, а также повышения производительности параллелизма программы, чтобы облегчить анализ проблемы и понимание схема, она также объясняет управление транзакциями Spring и выделяет несколько различных вариантов поведения распространения транзакций.

Деловые советы

Что такое бизнес? Проще говоря, транзакция — это логический набор операций, которые выполняются либо все, либо ни одна из них.

Что такое управление транзакциями? Так называемое управление транзакциями на самом деле представляет собой «выполнение операции фиксации или отката транзакции в соответствии с заданными правилами транзакции».

Большая часть механизма реализации транзакций опирается на файлы журнала транзакций (журнал отмен и журнал повторов). Журнал транзакций — это отдельный файл из файла базы данных. Он хранит все изменения, внесенные в базу данных, и полностью записывает вставки, обновления, удаления, фиксации, откаты и изменения схемы базы данных. Журнал транзакций является важным компонентом резервного копирования и восстановления.

Доставка заказа не удалась

Прежде чем пакет заказа будет выпущен со склада, в торговый центр будет отправлена ​​исходящая инструкция, которая содержит экспресс-информацию о пакете, чтобы платформа продаж могла отображать информацию об экспресс-отслеживании; если заказ был отменен, будет оцениваться, может ли заказ быть отправлен в соответствии со статусом возврата торгового центра.

Среди них процесс взаимодействия системы выглядит следующим образом: между фронтальной платформой продаж и WMS (системой управления складом) будет единая OMS (система управления заказами) для управления заказами на продажу и передачи данных.

Когда клиентская платформа продаж получает исходящую информацию, она выполняет следующие проверки и операции:

Для предотвращения исключений при вызове службы уведомлений, влияющих на доставку пакета, код, вызывающий службу уведомлений, обернут оператором try-catch.

Однако, когда некоторые заказы отсутствуют на складе, по-прежнему возникает следующее исключение, и выход со склада завершается сбоем:

org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only

	at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:873)
	at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:710)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:534)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:305)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)

В соответствии с поведением распространения транзакции,Transaction rolled back because it has been marked as rollback-onlyЭто должно быть потому, что вызванная транзакция откатывается, когда вызывающая сторона отправляет транзакцию, потому что она помечена какrollback-only, поэтому его нельзя отправить в обычном режиме.

Механизм распространения транзакций Spring

Давайте подробно поговорим о механизме распространения транзакций Spring.

Весна@TransactionalАннотации можно использовать для объявления того, что методы поддерживают транзакции, а нижний уровень Spring реализует управление транзакциями через АОП.

@Transactionalв примечанияхPropagationСвойства можно использовать для указания поведения распространения транзакции.

/**
    * The transaction propagation type.
    * <p>Defaults to {@link Propagation#REQUIRED}.
    * @see org.springframework.transaction.interceptor.TransactionAttribute#getPropagationBehavior()
    */
Propagation propagation() default Propagation.REQUIRED;

Следующие константы, представляющие поведение распространения, включены в определение TransactionDefinition:

  • TransactionDefinition.PROPAGATION_REQUIRES_NEW: Создайте новую транзакцию и приостановите текущую транзакцию, если есть текущая транзакция. Текущая транзакция не поддерживается.

  • TransactionDefinition.PROPAGATION_NOT_SUPPORTED: Запустить в нетранзакционном режиме, приостановить текущую транзакцию, если текущая транзакция есть. Текущая транзакция не поддерживается.

  • TransactionDefinition.PROPAGATION_NEVER:

Работает без транзакций и выдает исключение, если транзакция уже существует. Текущая транзакция не поддерживается.

  • TransactionDefinition.PROPAGATION_REQUIRED: Если транзакция уже существует, присоединиться к ней, если текущей транзакции нет, создать новую транзакцию. Текущая транзакция поддерживается.

  • TransactionDefinition.PROPAGATION_SUPPORTS: Если в данный момент есть транзакция, присоединиться к транзакции; если текущей транзакции нет, продолжить работу в нетранзакционном режиме. Текущая транзакция поддерживается.

  • TransactionDefinition.PROPAGATION_MANDATORY: Если в данный момент есть транзакция, присоединиться к транзакции; если текущей транзакции нет, сгенерировать исключение. Текущая транзакция поддерживается.

  • TransactionDefinition.PROPAGATION_NESTED: Если в данный момент транзакция существует, транзакция создается для выполнения как вложенная транзакция текущей транзакции; если текущей транзакции нет, значение эквивалентно TransactionDefinition.PROPAGATION_REQUIRED. Текущая транзакция поддерживается.

Здесь следует отметить, что предыдущие шесть вариантов поведения распространения транзакций были введены Spring из EJB, и они имеют одну и ту же концепцию. И PROPAGATION_NESTED специфичен для Spring. Транзакция, начатая с PROPAGATION_NESTED, встроена во внешнюю транзакцию (если есть внешняя транзакция), в настоящее время встроенная транзакция не является независимой транзакцией, она зависит от существования внешней транзакции, только через фиксацию внешней транзакции, может ли внутренняя транзакция быть вызвана фиксацией транзакций, вложенные подтранзакции не могут быть зафиксированы по отдельности. Если вы знакомы с концепцией точек сохранения в JDBC, вложенные транзакции легко понять. Фактически, вложенные подтранзакции являются приложением точек сохранения. Транзакция может включать несколько точек сохранения, и каждая вложенная подтранзакция является приложением точек сохранения. , субтранзакция. Кроме того, откат внешней транзакции также вызовет откат вложенных подтранзакций.

Решения, использующие поведение распространения транзакций

Основываясь на объяснении поведения распространения транзакции выше, поведение распространения транзакции может быть установлено какPROPAGATION_REQUIRES_NEW, так что текущая транзакция и вызываемая транзакция будут двумя разными транзакциями, которые можно зафиксировать или откатить соответственно.

Выполните следующий код после того, как внешняя транзакция поймает исключение, она выведетfalse, указывающий, что откат внутренней транзакции не распространяется на внешнюю транзакцию:TransactionAspectSupport.currentTransactionStatus().isRollbackOnly()

Выполните следующий код во внутренней транзакции, он вернетtrue, указывая, что внутренняя транзакция является новой транзакцией. При выполнении измененной транзакции текущая транзакция будет приостановлена:TransactionAspectSupport.currentTransactionStatus().isNewTransaction()

Это решает проблему, заключающуюся в том, что текущая транзакция не может быть зафиксирована из-за поведения распространения транзакции, когда блок try-catch генерирует исключение.

Решения, использующие многопоточность

Мы знаем, что транзакции между разными потоками независимы. Для таких служб, как отправка уведомлений, удобно создавать события, а затем обрабатывать их с помощью асинхронных прослушивателей.

Процесс выглядит следующим образом:

Что касается реализации модели событий, будь то распределенные Zookeeper, Redis и MQ или нераспределенные шины событий Guava и Spring Event, вы можете выбирать в соответствии с реальными потребностями. Основным принципом по-прежнему является модель публикации-подписки.

Ссылка на ссылку

Все аспекты транзакций базы данных

Вероятно, самое красивое подробное объяснение управления транзакциями Spring.

Транзакция должна знать, должна знать


Wechat-westcall