Java for Beginner
672 subscribers
540 photos
155 videos
12 files
827 links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Аннотация @Transactional

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

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

Пример базового использования:

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class PaymentService {

@Transactional
public void transferMoney(Long fromAccountId, Long toAccountId, double amount) {
// Операции с базой данных
debitAccount(fromAccountId, amount);
creditAccount(toAccountId, amount);
}

private void debitAccount(Long accountId, double amount) {
// Логика снятия средств
}

private void creditAccount(Long accountId, double amount) {
// Логика зачисления средств
}
}
В этом примере все операции внутри метода transferMoney выполняются в одной транзакции. Если любая операция завершится сбоем, все изменения будут откатаны.


Основные параметры @Transactional

@Transactional поддерживает ряд параметров, которые позволяют гибко управлять транзакциями:

propagation: Определяет, как должна быть организована транзакция при вызове метода.
REQUIRED (по умолчанию): Использует текущую транзакцию или создает новую.
REQUIRES_NEW: Всегда создает новую транзакцию.
NESTED: Создает вложенную транзакцию.
SUPPORTS: Метод может работать в контексте транзакции, но это не обязательно.


isolation: Уровень изоляции транзакции.
READ_UNCOMMITTED: Минимальная изоляция, данные могут быть "грязными".
READ_COMMITTED: Предотвращает "грязное" чтение.
REPEATABLE_READ: Предотвращает неповторяющееся чтение.
SERIALIZABLE: Максимальная изоляция, предотвращает все виды конфликтов.


timeout: Максимальное время выполнения транзакции в секундах.
readOnly: Указывает, что транзакция предназначена только для чтения данных.

rollbackFor и noRollbackFor: Исключения, при которых следует или не следует откатывать транзакцию.

Пример с параметрами:
@Transactional(
propagation = Propagation.REQUIRES_NEW,
isolation = Isolation.SERIALIZABLE,
timeout = 30,
rollbackFor = {RuntimeException.class},
readOnly = false
)
public void processTransaction() {
// Логика транзакции
}


Управление откатами

Spring автоматически откатывает транзакции, если метод генерирует RuntimeException или Error. Вы можете настроить это поведение с помощью rollbackFor.
@Transactional(rollbackFor = Exception.class)
public void updateDatabase() throws Exception {
// Если возникает Exception, транзакция будет откатана
}


Применение
@Transactional на уровне класса

Если аннотация используется на уровне класса, все методы будут выполняться в рамках транзакции.
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class OrderService {

public void createOrder() {
// Операции в транзакции
}

public void cancelOrder() {
// Операции в транзакции
}
}


Особенности работы с @Transactional

Прокси: Spring использует прокси-объекты для управления транзакциями. Это означает, что вызовы методов внутри одного класса могут не учитывать аннотацию
@Transactional.

Пример проблемы:
@Service
public class ExampleService {

@Transactional
public void method1() {
method2(); // method2 вызван напрямую, @Transactional не применяется
}

@Transactional
public void method2() {
// Логика method2
}
}
Только публичные методы: Аннотация работает только на публичных методах. Внутренние вызовы приватных или protected методов не активируют транзакцию.


#Java #Training #Spring #Transactional
Аннотация @Transactional

Аннотация @Transactional используется в Spring для управления транзакциями на уровне методов или классов. Она позволяет декларативно определять границы транзакций, их поведение и настройки. Аннотация находится в пакете org.springframework.transaction.annotation.

Параметры аннотации

value (необязательный):
Тип: String.
Значение по умолчанию: "".
Описание: Указывает имя менеджера транзакций (бина PlatformTransactionManager), который должен использоваться для управления транзакцией. Если не указано, используется менеджер транзакций по умолчанию.


Пример:
@Transactional("customTransactionManager")
public void performOperation() {
// Логика метода
}


propagation (необязательный):
Тип: Propagation.
Значение по умолчанию: Propagation.REQUIRED.
Описание: Определяет поведение распространения транзакции.


Возможные значения:
REQUIRED: Использует текущую транзакцию, если она существует, или создает новую.
REQUIRES_NEW: Всегда создает новую транзакцию, приостанавливая текущую, если она существует.
SUPPORTS: Использует текущую транзакцию, если она существует, но не создает новую.
NOT_SUPPORTED: Выполняет метод вне транзакции, приостанавливая текущую, если она существует.
MANDATORY: Требует наличия активной транзакции, иначе выбрасывает исключение.
NEVER: Запрещает выполнение метода в транзакции, иначе выбрасывает исключение.
NESTED: Создает вложенную транзакцию, если текущая транзакция существует.


Пример:
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void performOperation() {
// Логика метода
}


isolation (необязательный):
Тип: Isolation.
Значение по умолчанию: Isolation.DEFAULT.
Описание: Определяет уровень изоляции транзакции.


Возможные значения:
DEFAULT: Использует уровень изоляции по умолчанию для базы данных.
READ_UNCOMMITTED: Позволяет читать незафиксированные изменения других транзакций.
READ_COMMITTED: Гарантирует, что читаются только зафиксированные данные.
REPEATABLE_READ: Гарантирует, что данные, прочитанные в транзакции, не изменятся другими транзакциями.
SERIALIZABLE: Самый строгий уровень изоляции, предотвращает любые конфликты.


Пример:
@Transactional(isolation = Isolation.READ_COMMITTED)
public void performOperation() {
// Логика метода
}


timeout (необязательный):
Тип: int.
Значение по умолчанию: -1 (без тайм-аута).
Описание: Указывает максимальное время выполнения транзакции в секундах. Если время превышено, транзакция откатывается.


Пример:
@Transactional(timeout = 10)
public void performOperation() {
// Логика метода
}


readOnly (необязательный)
Тип: boolean.
Значение по умолчанию: false.
Описание: Указывает, является ли транзакция только для чтения. Если true, это может оптимизировать выполнение запросов.


Пример:
@Transactional(readOnly = true)
public void readData() {
// Логика метода
}


rollbackFor (необязательный):
Тип: Class<? extends Throwable>[].
Значение по умолчанию: {}.
Описание: Указывает типы исключений, при которых транзакция должна быть откачена. По умолчанию откат происходит только для непроверяемых исключений (RuntimeException и его подклассов).


Пример:
@Transactional(rollbackFor = {CustomException.class})
public void performOperation() throws CustomException {
// Логика метода
}


noRollbackFor (необязательный):
Тип: Class<? extends Throwable>[].
Значение по умолчанию: {}.
Описание: Указывает типы исключений, при которых транзакция не должна быть откачена.


Пример:
@Transactional(noRollbackFor = {CustomException.class})
public void performOperation() throws CustomException {
// Логика метода
}


#Java #Training #Hard #Spring #SpringDataJPA #Transactional
Жизненный цикл аннотации

Инициализация:
Аннотация @Transactional обрабатывается во время инициализации Spring-контекста. Spring создает прокси-объекты для методов или классов, помеченных @Transactional.

Выполнение:
Когда метод вызывается, Spring проверяет настройки транзакции и начинает новую транзакцию (или использует существующую) в соответствии с параметрами propagation.
Если метод завершается успешно, транзакция фиксируется (commit). Если возникает исключение, транзакция откатывается (rollback), если это указано в параметрах.


Уничтожение:

После завершения метода транзакция завершается (фиксируется или откатывается), и ресурсы освобождаются.

Механизмы Spring и настройки Spring Boot

Spring AOP (Aspect-Oriented Programming):

Spring использует AOP для создания прокси-объектов, которые перехватывают вызовы методов, помеченных @Transactional, и управляют транзакциями.

PlatformTransactionManager:
Spring предоставляет интерфейс PlatformTransactionManager для управления транзакциями. Реализации включают DataSourceTransactionManager (для JDBC) и JpaTransactionManager (для JPA).

TransactionTemplate:
Для программного управления транзакциями можно использовать TransactionTemplate.

Варианты настройки

Использование нескольких менеджеров транзакций:
Если в приложении используется несколько источников данных, можно настроить несколько менеджеров транзакций и указывать их в параметре value аннотации @Transactional.

Программное управление транзакциями:
Для сложных сценариев можно использовать TransactionTemplate:
@Autowired
private TransactionTemplate transactionTemplate;

public void performOperation() {
transactionTemplate.execute(status -> {
// Логика метода
return null;
});
}


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

#Java #Training #Hard #Spring #SpringDataJPA #Transactional