У нас есть проблема в приложении Spring Boot, где некоторые файлы создаются во время транзакции базы данных, и их необходимо удалить, если транзакция откатывается. Это мое решение…
Когда файл создается, мы публикуем событие, содержащее имя файла:
applicationEventPublisher.publishEvent(new FileCreatedEvent(this, filename));
У нас есть еще один компонент, который прослушивает событие:
@TransactionalEventListener(phase = TransactionPhase.AFTER_ROLLBACK)
public void handleRollback(FileCreatedEvent event) {
fileDeleter.delete(event.getFilename());
}
Как вы можете видеть, Spring Framework предоставляет функцию управления событиями pub/sub, где вы можете опубликовать событие с помощью Applicationeventпубликатор (который легко можно подключить автоматически). Затем вы можете подписаться на событие, используя @Transactioneventlistener аннотацию ^1 , которую можно настроить для запуска только после отката, установив параметр фазы в аннотации на AFTER_ROLLBACK (как показано).
Важно отметить, что события не доставляются слушателю до тех пор, пока транзакция не разрешится. Это значительно упрощает логику транзакций. Кроме того, это работает с несколькими одновременными событиями, прикрепленными к одной и той же транзакции, что означает, что вы можете запускать отдельные события для каждого файла, и каждое событие будет доставлено по завершении транзакции.
Еще одним потенциальным применением этого шаблона было бы предотвращение вводящих в заблуждение записей журнала/аудита путем запуска события для новой записи, но записи события только в том случае, если и когда транзакция успешно фиксируется. Таким образом, вы не увидите сообщений журнала с надписью “создан новый объект в базе данных”, если только новый объект действительно не был создан.
^1 Этот шаблон также работает без транзакций, если вы подписываетесь с помощью простого @EventListener . В этом случае событие будет обработано слушателем немедленно, а не ждать окончания транзакции.
Оригинал: “https://dev.to/virtualmackem/attaching-actions-to-rollbacks-in-spring-g1g”