Java Разработка | Spring Boot Backend & Architecture. Программирование на Джава для Developer. IT Собеседования, Алгоритмы и Coding задачи. Уроки и курсы для роста в Tech.
Наука · 3 сентября 2026 г.
💡 Чем опасен @Scheduled(fixedRate) без @Transactional? — 3 сентября 2026 г. в 06:12:18.801
💡 Чем опасен @Scheduled(fixedRate) без @Transactional? Расписание в Spring через @Scheduled — удобный способ запускать задачи по таймеру. Но часто разработчики забывают про транзакции, особенно с fixedRate, и попадают в ловушку. 📌 Пример проблемы: @Scheduled(fixedRate = 10_000) public void cleanUp() { List<Job> jobs = jobRepository.findAllByStatus(PENDING); jobs.forEach(job -> { job.setStatus(PROCESSING); jobRepository.save(job); }); } 🧨 Каждые 10 секунд метод запускается заново. Если выполнение предыдущего ещё не закончено, начнётся второй поток, который заберёт те же PENDING -записи. В итоге — дублирование обработки, гонки, повреждение данных. 📉 Особенно критично при долгих задачах или высокой нагрузке. ✅ Решение — обернуть метод в транзакцию + использовать блокировки: @Transactional @Scheduled(fixedRate = 10_000) public void cleanUp() { List<Job> jobs = jobRepository.findAllByStatusForUpdate(PENDING); // SELECT ... FOR UPDATE jobs.forEach(job -> { job.setStatus(PROCESSING); jobRepository.save(job); }); } 📌 Или добавить флаг “locked”, чтобы явно помечать взятые задачи. 💡 Лучше использовать @Scheduled(fixedDelay) — он ждёт завершения предыдущего запуска. Это безопаснее по умолчанию. 🧠 Подумайте о том, чтобы заменить @Scheduled на: * Spring Batch (если сложные джобы) * Spring Integration / Flowable / Camunda (если нужны гарантии и retry) * Quartz (если нужен контроль и очереди) 👉 @BookJava

