Откат файла при невозможности удалить файл из smb - PullRequest
0 голосов
/ 15 ноября 2018

У меня есть верблюжий маршрут, где производитель - это монтирование smb, а потребитель - очередь ActiveMQ.

Я хотел бы откатить транзакцию, когда SMB-сервер не может удалить файл из исходного монтирования SMB.Это, однако, происходит на этапе фиксации транзакции.

Я могу перехватить исключение при использовании onCompletionExceptionHandler , но перехват происходит ПОСЛЕ того, как объект Exchange, связанный с файлом, уже отправлен целевому ActiveMQ.

Есть лиспособ предотвратить верблюд транзакции в первую очередь или откат транзакции, чтобы сообщение не отправлялось в AMQ?Такое поведение присутствует в верблюде 2.17.2

1 Ответ

0 голосов
/ 17 ноября 2018

Давайте рассмотрим различные шаблоны доставки сообщений:

  • Как минимум один раз - сообщение удаляется из источника после его доставки в цель.Одно и то же сообщение может быть отправлено несколько раз.
    • Это то, что вы получили сейчас.
  • Не более одного раза - сообщение удаляется из источника, прежде чем оно будет доставлено в цель.Данные могут быть потеряны.
    • Скорее всего, не то, что вам нужно.
  • Ровно один раз - сообщение будет удалено из источника одновременно с доставкой его адресату.
    • Святой Грааль.Очень трудно достичь.

Хорошо, так что вы, по сути, хотите семантику Ровно .Этого можно достичь только при перемещении данных между очередями в одном и том же посреднике, между таблицами в базе данных или перемещением файла на локальный диск (или внутри одного и того же «ресурса»).

Когда выиметь несколько протоколов / ресурсов, это почти невозможно, или, по крайней мере, очень сложно.Есть несколько способов обеспечить точную однократную доставку с использованием транзакций «двухфазного принятия» с использованием распределенного координатора транзакций, такого как MSDTC в Windows или Atomikos в Java (среди прочих).Они будут поддерживать только транзакционные ресурсы, такие как очереди и базы данных, а не файловые системы, такие как SMB.

Другой способ - использовать sagas-pattern .Этот паттерн может быть немного излишним в этом случае.

Так что же делать?Хорошо - я могу придумать хотя бы один способ:

Идемпотентный потребительский паттерн .Это заставляет Camel хранить копии каждого сообщения (или, по крайней мере, ключа), такого как имя файла) в памяти, чтобы гарантировать, что ни одно сообщение не будет доставлено более одного раза.

// Something like this
from("smb://someplace?&idempotentKey=${file:name}&idempotent=true")
. // Whatnot
.to("activemq:queue:foobar");

Обратите внимание, что вы можете настроить идемпотентное хранилище для хранения записей в базе данных, на диске или в нескольких других местах, если вы хотите что-то более постоянное (но также и более сложное).

...