[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-spring-kak-rabotaet-transactional-v-spring":3},{"id":4,"slug":5,"topicId":6,"topicSlug":7,"topicName":8,"topicEmoji":9,"question":10,"answer":11,"codeLang":12,"codeSrc":12,"important":12,"commonMistakes":12,"modernUsage":12,"difficulty":13,"tags":14,"related":15,"progress":16,"seo":17},619,"kak-rabotaet-transactional-v-spring",14,"spring","Spring","🌱","Как работает @Transactional в Spring?","`@Transactional` -- аннотация для декларативного управления транзакциями. Spring оборачивает вызов метода в транзакцию через прокси: начинает перед выполнением, коммитит при успехе, откатывает при RuntimeException\u002FError. При checked exception по умолчанию -- commit.\n\n### Механизм работы\n\n1. Spring создаёт прокси вокруг бина с `@Transactional`\n2. При вызове метода прокси открывает транзакцию через `PlatformTransactionManager`\n3. При успехе -- commit\n4. При `RuntimeException` \u002F `Error` -- rollback\n5. При checked exception -- commit (по умолчанию!)\n\n```java\n@Service\npublic class TransferService {\n\n    @Transactional\n    public void transfer(Long fromId, Long toId, BigDecimal amount) {\n        Account from = accountRepository.findById(fromId).orElseThrow();\n        Account to = accountRepository.findById(toId).orElseThrow();\n        from.setBalance(from.getBalance().subtract(amount));\n        to.setBalance(to.getBalance().add(amount));\n        accountRepository.save(from);\n        accountRepository.save(to);\n        \u002F\u002F если здесь произойдёт RuntimeException -- все изменения откатятся\n    }\n}\n```\n\n### Основные параметры\n\n```java\n@Transactional(\n    propagation = Propagation.REQUIRED,        \u002F\u002F тип распространения\n    isolation = Isolation.READ_COMMITTED,       \u002F\u002F уровень изоляции\n    timeout = 30,                               \u002F\u002F таймаут в секундах\n    readOnly = true,                            \u002F\u002F только для чтения (оптимизация)\n    rollbackFor = Exception.class,              \u002F\u002F откат при checked exception\n    noRollbackFor = BusinessException.class     \u002F\u002F НЕ откатывать при этом исключении\n)\n```\n\n### readOnly = true\n\nПодсказка для оптимизации: Hibernate отключает dirty checking, база может использовать read-реплику:\n\n```java\n@Transactional(readOnly = true)\npublic List\u003CUser> findAllUsers() {\n    return userRepository.findAll();\n}\n```\n\n> **На собеседовании:** критически важно знать, что checked exception НЕ откатывает транзакцию по умолчанию. Для банковских операций всегда указывайте `rollbackFor = Exception.class`. Частая ошибка -- полагать, что любое исключение откатит транзакцию.","","middle",[7],[],null,{"title":18,"description":19,"ogTitle":18,"ogDescription":20,"keywords":21,"schemaAnswer":22,"featuredSnippetReady":23},"Как работает @Transactional в Spring? — Gymterview","`@Transactional` -- аннотация для декларативного управления транзакциями. Spring оборачивает вызов метода в транзакцию через прокси: начинает перед выполнением,","`@Transactional` -- аннотация для декларативного управления транзакциями. Spring оборачивает вызов метода в транзакцию ч",[7,13],"`@Transactional` -- аннотация для декларативного управления транзакциями. Spring оборачивает вызов метода в транзакцию через прокси: начинает перед выполнением, коммитит при успехе, откатывает при RuntimeException\u002FError. При checked exception по умолчанию -- commit.",true]