Кажется, что указанная комбинация SELECT / UPDATE решает проблему параллелизма с предложением UPDATE WHERE.Однако я бы склонялся к хранимой процедуре, если бы это было приемлемо: в зависимости от разновидности sql, хранимый процесс мог бы избавиться от проблемы параллелизма с атомарным «UPDATE ... RETURNING id INTO ...».
Относительно состояний, если они что-то вроде:
- 0 "можно получить"
- 1 "в процессе"
- 2 "завершено"
тогда состояние действует как замок.Может возникнуть проблема, если процесс прекратит работу после изменения состояния с 0 на 1, но до того, как задание будет фактически обработано: запись может оставаться заблокированной и необработанной до запуска задания очистки.Другой подход заключается в использовании отдельного столбца метки времени для блокировки.Затем запрос включает фильтр «WHERE now () - timeout> NVL (lockTimestamp, начало времени)», и блокировка выполняется установкой lockTimestamp в now () вместо того, чтобы полагаться на установку status = 1.Таким образом, блокировка может автоматически истечь после разумного ожидания (тайм-аута), и элемент снова становится доступным для получения следующим процессором.Работы по очистке не требуются.
Есть ли вероятность голодания, когда работа с низким приоритетом может быть не подобрана?
Нужно ли добавлять дополнительный заказ?Если все элементы имеют одинаковый приоритет, имеет ли значение, что обрабатывается первым (fifo, lifo)?
Полагаю, следует отметить, что если запущено несколько экземпляров этой процедуры выборки, то несколько очередейэлементы могут обрабатываться одновременно, и порядок обработки не обязательно является последовательным (process1 получает item1, process2 получает item2, process2 завершает item2, process1 завершает item1, ...), так что, надеюсь, это нормально, в противном случае блокировка должна проверить, что ничегоеще в процессе.
Я также не вижу особой необходимости в SELECT ... ДЛЯ ОБНОВЛЕНИЯ.