Apache Camel JDBC Опрос и идемпотентность
Я строю простой верблюжий маршрут, который должен постоянно опрашивать таблицу и отправлять данные в ActiveMQ. Каждый опрос должен извлекать только те данные, которые не были получены ранее. Лучший способ сделать это - отслеживать последний успешно обработанный идентификатор последовательности, а затем выбирать элементы, чей идентификатор последовательности больше, чем предыдущий.
Есть ли стандартный способ сделать это?
2 ответа
В многопользовательской базе данных возможно, чтобы строки с более низким идентификатором последовательности фиксировались после строк с более высоким идентификатором (конечно, в Oracle и SQLServer, я подозреваю, в любых dbms с поддержкой транзакций). В этом случае простое отслеживание последнего обработанного идентификатора может привести к появлению строк, которые никогда не обрабатываются.
Самое простое решение проблемы, если вы имеете контроль над схемой и единственная вещь, обрабатывающая эту таблицу, - это добавить в таблицу своего рода "обработанный" столбец и обновить этот столбец (как предлагает @Arnaud).
Если это не вариант, то есть 3 других механизма, которые я рассмотрел для решения этой проблемы:
- Добавьте триггер при вставке в свою таблицу, чтобы вставить запись в сопутствующую таблицу, которая ссылается на вашу таблицу и включает обработанный столбец. Измените запрос, чтобы объединить две таблицы, и пометьте строку как обработанную путем обновления сопутствующей таблицы таким же образом, как описано выше.
- Создайте сопутствующую таблицу и вставьте сюда строки, чтобы отметить строку в основной таблице как обработанную. Ваш опросный запрос затем должен будет найти строки, которых нет в сопутствующей таблице.
- Отслеживайте любые недостающие идентификаторы последовательности. Ищите тех, кто явно в каждом опросе.
Я выбрал 2, так как его было проще реализовать независимо от СУБД, и потребовалась просто вставка, чтобы пометить строку как обработанную.
В документации Camel для компонента sql есть свойство onConsume:
"... После обработки каждой строки этот запрос может быть выполнен, если Exchange был успешно обработан, например, чтобы пометить строку как обработанную..."