LINUX.ORG.RU

Как сочетать очередь и БД надёжно и транзакционно?

 ,


0

4

Есть два процесса, работающих с одними данными. Один процесс изменяет данные. К примеру создаёт новую запись. Второй процесс должен понять, что запись создалась и обработать её.

У меня возникают проблемы с тем, как правильно спроектировать транзакцию в БД и работу с очередью.

Первый подход:

  1. Вставляем строку
  2. Коммитим транзакцию.
  3. Отправляем в очередь событие с ID строки.
  4. Получатель получает событие.
  5. Получатель запрашивает данные по ID и работает с ними.

Тут возникает проблема между шагами 2 и 3. Если процесс умер, то запись окажется в БД, а получатель про это не узнает.

Второй подход:

  1. Вставляем строку
  2. Отправляем в очередь событие с ID строки.
  3. Коммитим транзакцию.
  4. Получатель получает событие.
  5. Получатель запрашивает данные по ID и работает с ними.

Тут тоже возникает проблема между шагами 2 и 3. Во-первых транзакция может не закоммититься, а событие уже ушло. Во-вторых получатель может получить событие раньше, чем транзакция закоммитится и не увидит данные.

Можно накрутить какую-то сложную архитектуру с дополнительным полем-статусом, двумя коммитами, «восстановлением» если второй коммит не сработал, получателем, который нормально отрабатывает двойные сообщения. Расписывать не буду, но это всё прям очень сложно выходит.

Самый простой вариант это использовать что-то вроде postgres listen/notify, который умеет отсылать события транзакционно. Но интересует именно работа с внешней очередью, без всяких там двухфазных транзакций и подобного энтерпрайза. Кажется, будто упускаю что-то очевидное.

Если нужна конкретика - пускай будет postgres и kafka

★★★★★

Последнее исправление: vbr (всего исправлений: 1)