Quantcast
Channel: SQL.ru: Firebird, InterBase
Viewing all articles
Browse latest Browse all 1677

SELECT и UPDATE одной записи таблицы в одной транзакции

$
0
0
FB 2.5
Есть таблица, назначение которой - хранить очередь заданий, с такой структурой:
CREATE TABLE TASKS (
ID INTEGER NOT NULL,
DATESTART TIMESTAMP,
ISACTIVE SMALLINT NOT NULL,
ISDONE SMALLINT NOT NULL,
<еще несколько полей>
);
Здесь:
DATESTART - дата-время начала выполнения задачи
ISACTIVE - флаг 0/1 "задача взята в работу"
ISDONE - флаг 0/1 "задача выполнена".


Что делает приложение по обработке таких заданий:
1) Открывается читающая транзакция, запрашивается 1 самая старая не взятая еще в работу задача:
    SELECT 
FIRST 1
ID, <еще несколько полей>
FROM TASKS
WHERE (ISACTIVE = 0) AND (DATESTART <= CURRENT_TIMESTAMP)
ORDER BY DATESTART


2) Закрывается читающая транзакция и тут же открывается пищущая, в которой взятая в работу задача (с полученным на вышеописанном шаге ID) помечается как взятая в работу:
    UPDATE TASKS
SET ISACTIVE = 1
WHERE ID = :ID
после чего пишущая транзакция завершается. Далее задача обрабатывается сколько надо времени и в завершении аналогичным образом помечается как завершенная.

Все элементарно, логично и когда эти задания обрабатывает 1 или 2-3 программы-клиентов - то все работает нормально. Однако 2-3 программы-клиента не успевают обрабатывать весь поток заданий в необходимое время, поэтому экспериментальным путем было получено, что таких программ необходимо иметь около 12-16.
В таком случает все тоже работает бОльшую часть времени нормально, но встречаются случаи, когда из нескольких десятков заданий, какое-то одно могут взять одновременно 2 клиента. Т.е. может так совпасть, что за те несколько миллисекунд между 1 и 2 действием (взяли ID задачи, пометили ее) может отработать шаг "взяли ID задачи" на другом клиенте и тогда одна и та же задача выполнится дважды - а это проблема.

Если эти 2 действия (SELECT+UPDATE одной и той же записи) оформить в виде одной ХП, то возникает lock-конфликт, хотя может быть я не разобрался с параметрами транзакции, в которой надо запускать такую ХП.

Подскажите, как лучше реализовать подобную задачу?

Viewing all articles
Browse latest Browse all 1677

Trending Articles