Карта / Spring Data / @Transactional

@Transactional

@Transactional — одна аннотация, которая оборачивает метод в транзакцию базы данных (см. тему «Транзакции, ACID, уровни изоляции»), без ручного BEGIN/COMMIT/ROLLBACK.

@Service
class OrderService {

    @Transactional
    void createOrder(Order order) {
        orderRepository.save(order);
        inventoryService.decreaseStock(order);   // если упадёт — откатится и save() выше
        paymentService.charge(order);
    }
}

Если любая строка внутри метода бросит исключение — все изменения откатятся, как будто метод не выполнялся вообще. Если метод завершился без ошибок — транзакция автоматически коммитится.

Копнуть глубже

По умолчанию @Transactional откатывается только на RuntimeException, не на проверяемые (checked) исключения (см. тему «checked vs unchecked»). Если нужно откатить и на checked-исключение тоже:

@Transactional(rollbackFor = Exception.class)
void createOrder(Order order) throws CustomCheckedException { ... }

@Transactional — это тоже Proxy (см. тему «Как работают прокси»), как и @Cacheable — Spring оборачивает бин прокси-объектом, который открывает транзакцию до вызова реального метода и коммитит/откатывает после. Поэтому, как и с @Cacheable, вызов метода с @Transactional изнутри того же класса (this.createOrder()) не пройдёт через прокси — аннотация не сработает.

Read-only оптимизация для методов, которые только читают данные:

@Transactional(readOnly = true)
List<Order> getOrders() { ... }

Это подсказка базе данных не тратить ресурсы на отслеживание изменений — небольшой, но реальный прирост производительности на read-операциях.

🎤 Закрыл тему, если можешь объяснить:
• что делает `@Transactional` и когда происходит откат по умолчанию;
• почему `@Transactional` не сработает при вызове метода внутри того же класса (если дошёл до 2-го слоя).