Короткий ответ
При раздельной записи в БД и публикации в очередь без общей транзакции возможна рассинхронизация: БД обновилась, а сообщение не отправлено (или наоборот), поскольку это два независимых ресурса без атомарной гарантии между ними.
Как это работает подробнее
Последовательность «commit в БД, затем publish в очередь» оставляет окно между операциями, где процесс может упасть после коммита, до publish — сообщение не отправится, а данные уже изменены.
Пример кода
example.py
def mark_order_paid(order_id):
db.update_status(order_id, "paid") # коммит произошёл
# --- если процесс упадёт здесь, событие никогда не будет опубликовано ---
queue.publish("order.paid", {"order_id": order_id})Что использовать на практике
- Практика. Двухфазные транзакции (XA) между БД и большинством брокеров почти не используются из-за сложности и блокировок; практическое решение — Transactional Outbox либо change data capture.
Подводные камни
- Риск. Оборачивать публикацию в try/except и повторять при любой ошибке без идемпотентности на стороне consumer — снижает потерю, но может привести к дублям; игнорировать проблему вовсе.