Существуют различные подходы, и следующие два приходят мне в голову на данный момент.
(1) Использовать блокировки строк БД
Сделайте так, чтобы ваши узлы устанавливали исключительную блокировку строки БД (выберите для обновления) на запись, которую собирается обработать узел. Если узел может установить блокировку, то процесс может свободно обрабатывать запись. В противном случае узел должен попробовать другую запись, потому что какой-то другой узел заблокировал запись и в настоящее время обрабатывает запись. Вам следует рандомизировать выбор необработанных записей, чтобы несколько минимизировать шансы нескольких узлов, конкурирующих за обработку идентичных записей.
(2) Назначьте вашим узлам некоторые идентификаторы и заставьте ваши узлы использовать эти идентификаторы для выбора несвязанных записей из обработанного набора данных. Например, если у вас есть 10 узлов, присвойте им идентификаторы от 0 до 9. Затем разбейте необработанные записи на несвязанные наборы на основе идентификатора записи, применив некоторую функцию, которая производит числа от 0 до 9. Например, вы можете использовать функцию MOD. Затем ваши узлы будут выбирать только те необработанные записи, чей идентификатор равен идентификатору узла. Это очень просто реализовать в SQL, если вы можете назначить несколько уникальных и последовательных идентификаторов вашим узлам.
На вашем месте я бы выбрал второе решение.