Верно, поскольку никто, похоже, не поднимает этот вопрос, я продолжу здесь то, что было начато в комментариях:
Есть много решений для этого. В вашем случае с одним потоком обработки вы можете, например, захотеть сохранить только идентификаторы записей в очереди. Затем ThreadB может получить саму строку, чтобы убедиться, что статус действительно равен NEW
. Или используйте optimisti c блокировку с update table set status='IN_PROGRESS' where id=rowId and status='NEW'
и прекратите обработку этой строки при исключении.
Оптимизация блокировки - это весело, и вы также можете использовать ее, чтобы полностью избавиться от потока производителя. Представьте себе несколько потоков, обрабатывающих записи из базы данных. Каждый из них может выбрать запись и попытаться установить статус с блокировкой optimisti c, как в первом примере. Таким образом, вполне возможно получить много конфликтов за записи, так что каждый поток может получить N строк, где N - количество потоков, или вдвое больше. А затем попробуйте обработать первую строку, для которой удалось установить IN_PROGRESS
. Это решение делает систему менее сложной, и на одну вещь меньше нужно заботиться / синхронизироваться.
И вы можете заставить поток собирать не только записи, которые имеют NEW
, но и те, которые IN_PROGRESS
и started_date < sysdate = timeout
, которые будут включать записи, которые не были обработаны из-за сбоя системы (например, потоку удалось установить для одной строки значение IN_PROGRESS
, а затем ваша система вышла из строя. Таким образом, вы получите некоторую устойчивость здесь.