[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-spring-test-kak-rabotaet-transactional-v-testakh-i-chto-takoe-avtomaticheskiy-rollback":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},706,"kak-rabotaet-transactional-v-testakh-i-chto-takoe-avtomaticheskiy-rollback",16,"spring-test","Spring Test","🧪","Как работает Transactional в тестах и что такое автоматический rollback?","Когда тестовый метод или класс аннотирован `@Transactional`, Spring Test автоматически оборачивает каждый тест в транзакцию и откатывает её после завершения. Это гарантирует, что тестовые данные не загрязняют базу для последующих тестов.\n\n> **Аналогия из жизни:** это как черновик в текстовом редакторе — вы пишете, проверяете результат, а потом нажимаете «отменить» (Ctrl+Z), и документ возвращается в исходное состояние.\n\n```java\n@SpringBootTest\n@Transactional\nclass UserServiceTransactionalTest {\n\n    @Autowired\n    private UserService userService;\n\n    @Autowired\n    private UserRepository userRepository;\n\n    @Test\n    void shouldCreateUserAndRollback() {\n        userService.create(new UserDto(\"Иван\", \"ivan@example.com\"));\n        assertEquals(1, userRepository.count());\n        \u002F\u002F После теста транзакция откатится — данные не сохранятся\n    }\n\n    @Test\n    void shouldHaveEmptyDatabase() {\n        \u002F\u002F Благодаря rollback предыдущего теста, база чиста\n        assertEquals(0, userRepository.count());\n    }\n}\n```\n\n### Отключение отката\n\n```java\n@Test\n@Commit  \u002F\u002F или @Rollback(false)\nvoid shouldPersistData() {\n    userService.create(new UserDto(\"Иван\", \"ivan@example.com\"));\n    \u002F\u002F Данные останутся в базе после теста\n}\n```\n\n### Важные нюансы\n\n1. `@DataJpaTest` автоматически применяет `@Transactional` — дополнительно аннотировать не нужно.\n\n2. `@Transactional` в тестах не работает с `RANDOM_PORT` и `DEFINED_PORT`, потому что HTTP-запросы выполняются в отдельном потоке, а транзакция привязана к потоку теста:\n\n```java\n\u002F\u002F Rollback НЕ сработает — запросы идут через реальный HTTP\n@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)\n@Transactional\nclass WontRollbackTest {\n\n    @Autowired\n    private TestRestTemplate restTemplate;\n\n    @Test\n    void dataWillPersist() {\n        restTemplate.postForEntity(\"\u002Fapi\u002Fusers\",\n            new UserDto(\"Иван\"), UserDto.class);\n        \u002F\u002F Данные останутся в базе!\n    }\n}\n```\n\n3. Для очистки данных при интеграционных тестах с реальным сервером используйте `@Sql` с `AFTER_TEST_METHOD` или `@DirtiesContext`:\n\n```java\n@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)\nclass IntegrationTest {\n\n    @Test\n    @Sql(scripts = \"\u002Fcleanup.sql\",\n         executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)\n    void integrationTest() {\n        \u002F\u002F ...\n    }\n}\n```\n\n> **На собеседовании:** ключевой момент — объяснить, почему rollback не работает с `RANDOM_PORT` (разные потоки). Частая ошибка — не знать про эту особенность и ожидать откат при использовании `TestRestTemplate`.","","middle",[7],[],null,{"title":18,"description":19,"ogTitle":18,"ogDescription":20,"keywords":21,"schemaAnswer":22,"featuredSnippetReady":23},"Как работает Transactional в тестах и что такое автоматическ — Gymterview","Когда тестовый метод или класс аннотирован `@Transactional`, Spring Test автоматически оборачивает каждый тест в транзакцию и откатывает её после завершения. Эт","Когда тестовый метод или класс аннотирован `@Transactional`, Spring Test автоматически оборачивает каждый тест в транзак",[7,13],"Когда тестовый метод или класс аннотирован `@Transactional`, Spring Test автоматически оборачивает каждый тест в транзакцию и откатывает её после завершения. Это гарантирует, что тестовые данные не загрязняют базу для последующих тестов.",true]