Я использую mySQL из их C API, но это не должно относиться к делу.
Мой код должен обрабатывать записи из таблицы, которые соответствуют некоторым критериям, а затем обновлять указанные записи, чтобы пометить их как обработанные. Строки в таблице изменены / вставлены / удалены другим процессом, который я не контролирую. Я боюсь в следующем, ОБНОВЛЕНИЕ может пометить некоторые записи ошибочно, так как набор соответствия записей мог измениться между шагом 1 и шагом 3.
SELECT * FROM myTable WHERE <CONDITION>; # step 1
<iterate over the selected set of lines. This may take some time.> # step 2
UPDATE myTable SET processed=1 WHERE <CONDITION> # step 3
Какой разумный способ обеспечить, чтобы ОБНОВЛЕНИЕ обновляло все обработанные строки и только их? Кажется, что транзакция не соответствует требованиям, так как она не обеспечивает такого рода изоляцию: недавно измененная запись, не входящая в первоначально выбранный набор, все еще может быть целью оператора UPDATE. По той же причине, SELECT ... FOR UPDATE, похоже, не помогает, хотя звучит многообещающе: -)
Единственный способ увидеть это - использовать временную таблицу для запоминания набора строк, которые нужно обработать, делая что-то вроде:
CREATE TEMPORARY TABLE workOrder (jobId INT(11));
INSERT INTO workOrder SELECT myID as jobId FROM myTable WHERE <CONDITION>;
SELECT * FROM myTable WHERE myID IN (SELECT * FROM workOrder);
<iterate over the selected set of lines. This may take some time.>
UPDATE myTable SET processed=1 WHERE myID IN (SELECT * FROM workOrder);
DROP TABLE workOrder;
Но это кажется расточительным и не очень эффективным.
Есть ли что-нибудь умнее?
Большое спасибо новичку в SQL.