Что такое транзакция?
Транзакция — это серия событий, которые вместе преуспевают или терпят неудачу.
Если каждая из транзакций успешна, она фиксируется, если какая-либо из них не удалась
это событие, когда все транзакции принимаются как неуспешные и происходит откат. Этот процесс обеспечивает нам целостность данных.
Типы транзакций
Транзакции делятся на глобальные и локальные в зависимости от их использования.
Как показано в примере с заказом выше, когда пользователь отправляет запрос на заказ в монолитную систему, соответствующие транзакции записываются в общую базу данных. В случае ошибки он может быть свернут как единая структура.
Когда система переходит от монолитной к микросервисной архитектуре, создаются два разных сервиса для операций с клиентами и заказами и разделяются соответствующие базы данных.
В этом случае транзакции, необходимые для двух услуг, должны управляться отдельно. Поскольку транзакция теперь находится в нескольких базах данных, она считается распределенной транзакцией.
Свойства транзакции
При управлении транзакциями необходимо учитывать следующие вопросы;
- Восстановление после сбоев (атомарность, долговечность).
- Контроль параллелизма (изоляция, согласованность).
Применение принципов ACID позволяет нам выполнить здоровую транзакцию.
Automicity
Он рассматривает сделку как единое целое. Обновление данных в нескольких базах данных/таблицах происходит во время транзакции
все они будут иметь успех или потерпят неудачу одновременно
Последовательность
Начальное и конечное состояния данных, затронутых транзакцией, должны быть согласованными. Ошибка, возникающая во время транзакции, не позволяет непредвиденным образом повлиять на состояние системы.
Изоляция
Одновременно с одними и теми же данными может происходить более одной транзакции. Для того чтобы транзакции не были подвержены влиянию транзакций друг друга, транзакции должны выполняться последовательно. Во время транзакции наборы данных блокируются до успешного или неуспешного завершения транзакции.
Долговечность
Это способность системы возвращаться к предыдущему состоянию достоверных данных в случае физической или операционной ошибки во время транзакции.
Что такое управление транзакциями?
Можно контролировать, в рамках каких правил будут работать используемые транзакции.
Использование Spring Proxy
Spring использует прокси вместо прямого вызова классов или методов, использующих транзакционную аннотацию. Это помогает провести различие между транзакционной логикой и бизнес-логикой.
Например, пусть структура будет такой, как показано ниже.
Когда происходит вызов класса AccountService;
Здесь вмешивается прокси-структура, и мы получаем доступ к нужному классу или методу через эту структуру.
Типы управления транзакциями
Spring предлагает два метода управления транзакциями. Программный и декларативный
Programmematic
Это метод, который содержит коды управления транзакциями (фиксация, откат).
@Override
public void transferMoney(Account from, Account to, double amount, double fee) {
TransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
TransactionStatus transactionStatus = transactionManager.getTransaction(transactionDefinition);
try {
withdraw(from, amount, fee);
deposit(to, amount);
transactionManager.commit(transactionStatus);
} catch (RuntimeException e) {
transactionManager.rollback(transactionStatus);
throw e;
}
}
Декларативный
Он выполняется Spring Container в рамках некоторых правил в инфраструктуре Spring.
- Это делается благодаря @Transactional Annotation
@Override
@Transactional
public void transferMoney(Account from, Account to, double amount, double fee){
withdraw(from, amount, fee);
deposit(to, amount);
}
Есть несколько типов транзакций, которые мы имеем в этой форме управления транзакциями.
- Тип распространения
- Уровень изоляции
- Длительность тайм-аута
- флаг readOnly
- Правило отката
Распространение
Это свойство, в котором мы обрабатываем поведение после начала транзакции. В соответствии с этим определением определяется следующее поведение транзакции.
- РЕКВИЗИТНОЕ распространение
REQUIRED — это техника распространения по умолчанию. Spring проверяет наличие активной транзакции и создает новую, если ее нет. В противном случае транзакции добавляются к активной транзакции:
@Transactional(propagation = Propagation.REQUIRED)
public void requiredExample(String user) {
// ...
}
-
REQUIRES_NEW Распространение
Вместо того чтобы использовать существующую транзакцию, требуется создать новую транзакцию, приостановив ее. Когда новая транзакция завершается, приостановленная транзакция возвращается.
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void requiresNewExample(String user) {
// ...
}
-
ПОДДЕРЖКИ Размножение
Если есть активная транзакция, он включается в нее, а если нет, то демонстрирует нетранзакционное поведение.
@Transactional(propagation = Propagation.SUPPORTS)
public void supportsExample(String user) {
// ...
}
- NOT_SUPPORTED Распространение
Если существует существующая активная транзакция, вместо того, чтобы использовать ее, она приостанавливает ее и выполняет транзакции нетранзакционно.
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void notSupportedExample(String user) {
// ...
}
- ОБЯЗАТЕЛЬНО Распространение
Если активная транзакция найдена, она включается в него, если же нет, то выбрасывается IllegalTransactionStateException.
@Transactional(propagation = Propagation.MANDATORY)
public void mandatoryExample(String user) {
// ...
}
- распространение НИКОГДА
Выбрасывает исключение IllegalTransactionStateException, если существует активная транзакция, в противном случае выполняет нетранзакционные транзакции.
@Transactional(propagation = Propagation.NEVER)
public void neverExample(String user) {
// ...
}
Изоляция
Он используется для манипулирования данными в каждой транзакции.
- READ_UNCOMMITTED Изоляция
Это позволяет считывать изменения данных в других транзакциях из текущей транзакции до их фиксации.
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void log(String message) {
// ...
}
- READ_COMMITTED Изоляция
Предотвращает чтение изменений данных в других транзакциях до их фиксации.
@Transactional(isolation = Isolation.READ_COMMITTED)
public void log(String message) {
// ...
}
-
REPEATABLE_READ Изоляция
- Позволяет одновременно читать во время удаления или добавления новой записи.
@Transactional(isolation = Isolation.REPEATABLE_READ)
public void log(String message) {
// ...
}
- СЕРИЛИЗУЕМОСТЬ Изоляция
Это метод изоляции самого высокого уровня. Когда транзакция выполняется над записью, эта запись блокируется, и другие транзакции не могут работать над ней.
@Transactional(isolation = Isolation.SERIALIZABLE)
public void log(String message) {
// ...
}
Откат
Можно указать типы Исключений, для которых мы хотим выполнить операцию отката транзакции, и не выполнять ее.
@Transactional(rollBackFor = NullPointerException.class)
public void method(String message) {
// ...
}
@Transactional(noRollBackFor = NullPointerException.class)
public void method(String message) {
// ...
}
Также по умолчанию rollBackFor установлен для RunTimeException.
Тайм-аут
Она обеспечивает автоматическое завершение сделки, если она не может быть завершена по истечении определенного периода времени. По умолчанию он составляет 60 секунд.
@Transactional(timeout = 15)
public void method(String message) {
// ...
}
Только чтение
Используется для указания того, что транзакция будет использоваться только для чтения. Это обеспечивает соответствующую оптимизацию доступа к данным.
@Transactional(readOnly = true)
public void method(String message) {
// ...
}