Собственное использование Spring АОП - принцип транзакций Spring

Java

aop — это аспектно-ориентированное программирование, аспектно-ориентированное программирование.

  • Аспект: Аспект. Во время выполнения кода всегда есть какая-то логика, которая одинакова в нескольких модулях.В это время эти несколько мест с одинаковой логикой обработки могут обрабатываться в одном месте. Этот вид обработки похож на разрезание ножом по горизонтали в каждом файле модуля кода, вставка новой части логики, файл кода этой новой логики подобен поперечному сечению всего кода, после обработки этой плоскости Вернуться к оригинальная логика выполнения
  • Точка присоединения: место, где выполняется общедоступная программа.Для весны это представляет выполнение метода (можно выбрать AspectJ для поддержки обновления поля)
  • Point cut: адаптируйте все выражения Join Point для фильтрации и выполнения общих методов кода.
  • Совет: Код, который реально выполняется в аспекте, он может быть до выполнения метода, после выполнения, где выбрасывается исключение и т.д.
  • Целевой объект: после выполнения аспекта исходная программа должна выполнить содержимое.Для аспекта это объект, который должен быть выполнен его прокси.
  • Советник: реализация кода, отвечающая за организацию отношений между советами/точечными разрезами/представляемыми объектами.

Введение в документацию Spring 4.2.x

Используется в коде AOP

Вы можете использовать xml или аннотацию для использования aop в проекте.Возьмите аннотацию в качестве примера.Как правило, вы можете обратиться к AspectJ, создать класс самостоятельно и пометить класс аннотациями.@Aspect

@Aspect
public class LogAspect {}

Откройте сканирование в xml, чтобы найти эту аннотацию

<aop:aspectj-autoproxy />

Создайте соответствующий в кодеPoint Cut

  @Pointcut("execution(* paxi.maokitty.verify.spring.aop.service.ExecuteService.*(..))")
    public void allClassPointCut(){}

Здесь выражение PointCut указывает, что все методы класса paxi.maokitty.verify.spring.aop.service.ExecuteService являются целевым объектом.

Создайте свой собственный метод, который необходимо выполнить (advice)

  @Before("allClassPointCut()")
    public void beforeAspectExecuteService(JoinPoint joinPoint){
        LOG.info("beforeAspectExecuteService execute method:{}",new Object[]{joinPoint.getStaticPart().toShortString()});
    }

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

Чтобы организовать aop по коду, вы можете нажать здесь

Использование aop транзакциями весной

дела

Распределенные транзакции здесь не обсуждаются

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

  • Атомарность: все операции в транзакции либо завершаются успешно, либо терпят неудачу.
  • Непротиворечивость: обеспечение перехода базы данных из одного согласованного состояния в другое согласованное состояние.
  • Изоляция: одновременное выполнение нескольких транзакций не повлияет друг на друга.
  • Постоянство: изменения в базе данных совершенными транзакциями должны постоянно храниться в базе данных.

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

Реализация транзакции в Java-коде

Ключевыми классами для управления операциями с базой данных в Java являютсяConnection, который представляет собой соединение с базой данных через соответствующий метод

  • connection.commit(): Семантика отправки для выполнения транзакций.
  • con.rollback();: выполнить семантику отката транзакции. Может управлять транзакционными операциями

Демонстрационный экземпляр транзакции нажмите здесь
Полный анализ обработки транзакций Java - Требуется программист

Использование транзакций весной

Простейшая реализация в spring просто требует добавления аннотации непосредственно в класс, который будет использовать транзакцию.@Transactionalи добавьте аннотированное сканирование в xml<tx:annotation-driven transaction-manager="txManagerTest"/>В принципе, вы можете использовать весенние транзакции

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

Реализация транзакций в Spring достигается с помощью aop. Когда Spring сканирует тег tx, когда он встречает класс или метод, отмеченный транзакцией, он создает соответствующий прокси-сервер AOP, и когда он вызывается, прокси-сервер AOP выполняет его метод, если есть проблема, выполняет соответствующий сделка

 @Trace(
            index = 13,
            originClassName = "org.springframework.transaction.interceptor.TransactionAspectSupport",
            function = "protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,final InvocationCallback invocation) throws Throwable"
    )
    public void  invokeWithinTransaction(){
        //...
        Code.SLICE.source("final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);")
                .interpretation("查到对应方法的事务配置");
        Code.SLICE.source("final PlatformTransactionManager tm = determineTransactionManager(txAttr);")
                .interpretation("拿到transactionManager,比如用户在xml中配置的 org.springframework.jdbc.datasource.DataSourceTransactionManager");
        Code.SLICE.source("final String joinpointIdentification = methodIdentification(method, targetClass);")
                .interpretation("获取transaction标注的方法");
        //...
        Code.SLICE.source("TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);\n" +
                "   Object retVal = null;\n" +
                "   try {\n" +
                "    retVal = invocation.proceedWithInvocation();\n" +
                "   }\n" +
                "   catch (Throwable ex) {\n" +
                "    // target invocation exception\n" +
                "    completeTransactionAfterThrowing(txInfo, ex);\n" +
                "    throw ex;\n" +
                "   }\n" +
                "   finally {\n" +
                "    cleanupTransactionInfo(txInfo);\n" +
                "   }\n" +
                "   commitTransactionAfterReturning(txInfo);\n" +
                "   return retVal;")
                .interpretation("这里就是标准的事务处理流程  1:获取事务;2:执行用户自己的方法;3:如果执行过程中抛出了异常执行异常抛出后的事务处理逻辑 4:清除事务信息 5:提交事务");
        //...
    }

Spring сканирует аннотации tx для выполнения деталей отслеживания кода транзакции, нажмите здесь

Логика выполнения конкретной транзакции Spring

Spring настраивает логику распространения транзакций

  • PROPAGATION_REQUIRED :如果没有事务就新建一个,有的话就在那个事务里面执行。 распределение по умолчанию
  • PROPAGATION_SUPPORTS: ничего не делать без транзакции, выполнять в текущей транзакции, если транзакция есть
  • PROPAGATION_MANDATORY: создать исключение, если транзакции нет.
  • PROPAGATION_REQUIRES_NEW: Создайте новую транзакцию. Если транзакция уже существует, сначала приостановите ее, а затем возобновите после выполнения новой транзакции.
  • PROPAGATION_NOT_SUPPORTED: метод не будет выполняться в транзакции, если транзакция есть, она будет приостановлена ​​на время выполнения метода.
  • PROPAGATION_NEVER: генерирует исключение, если есть транзакция
  • PROPAGATION_NESTED: если транзакция уже существует, вложить другое выполнение. Вложенную транзакцию можно зафиксировать или откатить независимо от инкапсулированной транзакции. Если транзакции нет, будет создана новая транзакция.

Вот разница между так называемой физической транзакцией и логической транзакцией

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

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

  • TRANSACTION_READ_UNCOMMITTED: строка изменений данных в транзакции будет прочитана другой транзакцией до того, как она будет фактически зафиксирована, то есть, если транзакция, которая изменила данные, откатывается, данные, прочитанные другими потоками, недействительны.
  • TRANSACTION_READ_COMMITTED: изменение строки данных в транзакции может быть прочитано только после фиксации данных.
  • TRANSACTION_REPEATABLE_READ: изменение строки данных в транзакции может быть прочитано только после фиксации данных. Две транзакции, одна транзакция читает строку данных, а другая транзакция немедленно изменяет ее.Если первая транзакция снова читает данные, данные, которые она читает, остаются такими же, как и раньше.
  • TRANSACTION_SERIALIZABLE: после того, как транзакция считывает данные, удовлетворяющие условию where, другая транзакция одновременно вставляет строку данных, удовлетворяющую этому условию.Первая транзакция читает снова, но не считывает новые данные.

Механизм изоляции транзакций и механизм распространения Аннотации исходного кода объясняют их значение, что на самом деле является определением Connection

Грязные чтения, неповторяемые чтения и фантомные чтения происходят для разных механизмов изоляции.

Y означает, что он будет существовать, N означает, что он не существует

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

Конкретный исходный код реализации пружины

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

if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
	throw new IllegalTransactionStateException(
		"Existing transaction found for transaction marked with propagation 'never'");
	}

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

Мой блог будет синхронизирован с Tencent Cloud + Community, и я приглашаю всех присоединиться:cloud.Tencent.com/developer/ это…