30 фотографий для анализа: исходный код весенней транзакции

Java
30 фотографий для анализа: исходный код весенней транзакции

я自学войти на завод高级java开发Инженер, поиск WeChat【IT老哥] Следуйте за этим программистом-самоучкой.

Brother разобрался с последними обновлениями производителей первого эшелона в 2020 годуjava面试题汇总, охватывающей различные технические области Java, вы можете получить, ответив на вопросы интервью.

предисловие

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

Это требует анализаSpring的核心源码, и, наконец, найти причину проблемы и решения.

Процесс выполнения транзакции аннотации

Давайте сначала посмотрим на базовый рабочий процесс транзакций Spring.

отношение основного объекта

1. Конфигурация транзакции

TransactionManagementConfigurationSelector: Импортировать зарегистрированный компонент конфигурации, когда конфигурация запускает запуск транзакции (EnableTransactionManagement).

Он включает в себя два блока конфигурации, AutoProxyRegistrar и ProxyTransactionManagementConfiguration.

AutoProxyRegistrar: отвечает за настройку соответствующих свойств транзакции внедрения зависимостей и класса входа транзакции внедрения (класс InfrastructureAdvisorAutoProxyCreator);

ProxyTransactionManagementConfiguration: Отвечает за внедрение bean-компонентов, связанных с транзакциями, в том числе:

  • Компонент аспекта транзакции (BeanFactoryTransactionAttributeSourceAdvisor)

  • TransactionAttributeSource (бин атрибута конфигурации транзакции)

  • TransactionInterceptor (бин-перехватчик транзакций);

2. Перехват операций, связанных с транзакциями

  • AopProxy: базовый интерфейс динамического прокси-сервера Spring AOP, отвечающий за определение основного поведения прокси-сервера;

  • MethodInterceptor: внутренний основной интерфейс перехватчика в цепочке вызовов Spring AOP, все типы аспектов в конечном итоге будут упакованы в этот интерфейс для запуска унифицированного перехвата;

  • TransactionInterceptor: основная бизнес-реализация перехватчика транзакций Spring и цепочка вызовов AOP, наконец, запускает его метод вызова;

  • TransactionManager: базовый интерфейс, управляемый Spring, который выделяется как интерфейс верхнего уровня подинтерфейса и не определяет фактическое поведение транзакции;

  • PlatformTransactionManager: наследует TransactionManager, определяет транзакции и основное поведение;

  • AbstractPlatformTransactionManager: отвечает за реализацию общедоступного поведения и общей логики реализации во всем управлении транзакциями и запущенном процессе, он наследуется от интерфейса PlatformTransactionManager;

реализация исходного кода

Далее давайте проанализируем исходный код транзакции Spring, в этом процессе будут разделены некоторые ямы и важные выводы.

1. Конфигурация транзакции

TransactionManagementConfigurationSelector.selectImports() отвечает за определение классов конфигурации, которые извне добавляются в контейнер Spring.

Этот метод, наконец, разрешается в ConfigurationClassParser и, наконец, создается как bean-компонент.

AutoProxyRegistrar.registerBeanDefinitions() регистрирует определение компонента с помощью InfrastructureAdvisorAutoProxyCreator.

ProxyTransactionManagementConfiguration.transactionAdvisor() внедряет аспекты транзакции

2. Создание транзакций

Одна из фактически запущенных записей (и cglib): JdkDynamicAopProxy..invoke()

Основной метод обработки цепочки вызовов аспектов ReflectiveMethodInvocation.proceed()

TransactionInterceptor.invoke() запускает перехват транзакций отсюда

TransactionAspectSupport.invokeWithinTransaction() реализует основной бизнес транзакций Spring.

TransactionAspectSupport.determineTransactionManager() определяет указанный менеджер транзакций.

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

createTransactionIfNecessary() создает информацию о транзакции TransactionInfo: включая источник данных, соединение транзакции (ConnectionHolder), статус транзакции, кеш соединения и т. д.;

DataSourceTransactionManager.doGetTransaction() Получает объект транзакции: пакет, который содержит подключение и кэширование

TransactionsynchronizationManager.getResource () Кэш класса подключаемого потока: убедитесь, что текущий поток получает уникальное подключение к данным

AbstractPlatformTransactionManager.startTransaction() запускает новую транзакцию

Только когда newTransaction имеет значение true, Spring выполнит фактическую фиксацию или откат, что здесь очень важно. Многие ямки вложенных транзакций здесь не совсем понятны.

DataSourceTransactionManager.doBegin() открывает исходный код ядра транзакции.

TransactionSynchronizationManager.bindResource() устанавливает привязку текущего соединения и источника данных на уровне потока.

3. Откат транзакции

Для непрограммных транзакций основной реализацией транзакций Spring на самом деле является парадигма упаковки отправки и отката транзакции с помощью try/catch, но упаковка при фиксации и откате очень специфична.

Реализация отката транзакции TransactionAspectSupport.completeTransactionAfterThrowing()

На приведенном выше снимке экрана doSetRollbackOnly() на самом деле не установит точку отката на соединении, а только пометит ее (текущую транзакцию нужно откатить, и метка будет использоваться при фиксации)!

4. Представление сделки

Транзакция AbstractPlatformTransactionManager.commit() фактически отправляет сюда исходный код.

cleanupAfterCompletion() перезапускает соединение или восстанавливает транзакцию, что интересно: когда атрибут распространения транзакции равен Require_New, предыдущее соединение будет временно приостановлено, а затем будет создано новое соединение; когда новое соединение фиксируется или откатывается, этот метод используется для восстановления предыдущего соединения и состояния! ! ! !

Хорошо, дела здесь, я делюсь десертом на вложенных подтранзакциях в соответствии с источником:

  • В процессе вложенной транзакции, если в середине есть какое-либо исключение, пока оно не заблокировано, оно будет выброшено, и последующий код не будет выполняться;

  • Пока атрибут распространения транзакции Require_New установлен, каждый метод аннотации Transactional будет отправлен или откатываться отдельно;

  • Вложенные транзакции будут создавать точки отката во вложенных транзакциях, за исключением первой аннотации Transactional;

  • После установки точки отката точки сохранения все транзакции перед текущим методом будут откатываться во время отката; если нужно откатить только текущий метод, добавьте try{}catch(){//no exception в самый внешний метод транзакции };

  • Объекты каждой транзакции разные, статус транзакции может быть разным, но связь может быть одинаковой;

Суммировать

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

需要我们根据源码的规律去分析每层子事务该如何流转! !所以需要把这块的源码搞熟,遇到复杂的嵌套事务分析原因,那问题就不大了。

wavebeed

В этой статье используетсяmdniceнабор текста