Можете ли вы сократить продолжительность транзакции? Вот что я имею в виду.
У вас есть значения состояния 0 для «ожидания» и 1 для «завершения». Используйте значение состояния 2 (или -1, или что вы выбираете), чтобы означать «работает».
Затем, когда рабочий поток получает задание из таблицы, он выполняет это (псевдо-SQL).
BEGIN TRANSACTION
SELECT id FROM ww_jobs_for_update WHERE status=0 ORDER BY id LIMIT 1 FOR UPDATE
UPDATE ww_jobs_for_update SET status=2 WHERE id = << db_id
COMMIT
Теперь ваш поток принял задание и снял блокировку транзакции. Когда работа завершена, вы просто делаете это, чтобы пометить ее как выполненную, без необходимости транзакции.
UPDATE ww_jobs_for_update SET status=1 WHERE id=" << db_id;
Существует еще более простой способ сделать это, если вы можете гарантировать, что каждый рабочий поток имеет уникальный идентификатор threadId
. Поместите в таблицу столбец thread
со значением NULL по умолчанию. Затем начать обработку задания.
UPDATE ww_jobs_for_update
SET thread = threadId, status = 2
WHERE status = 0 AND threadId IS NULL
ORDER BY id LIMIT 1;
SELECT id FROM ww_jobs_for_update WHERE thread = threadId AND status=2
Когда закончите
UPDATE ww_jobs_for_update
SET thread = NULL, status = 1
WHERE thread = threadId;
Поскольку каждый поток имеет уникальный threadId, а отдельные операторы SQL UPDATE сами по себе являются небольшими транзакциями, вы можете сделать это без использования каких-либо транзакций или фиксаций вообще.
Оба эти подхода имеют дополнительное преимущество, заключающееся в том, что вы можете использовать запрос SELECT, чтобы выяснить, какие задания являются активными. Это может позволить вам работать с заданиями, которые по какой-либо причине никогда не выполнялись.