Su solución con la bandera parece factible y creo que lo único que se necesita es hacer que el bloqueo caduque. Básicamente, la forma en que diseñaría el bloqueo es escribir una marca de tiempo cuando se tomó el bloqueo y hacer que el proceso tenga que actualizar el bloqueo de vez en cuando (es decir, cada 30 segundos) mientras todavía está trabajando en el registro. Si el proceso muere o no completa el trabajo, el bloqueo caducará y otros procesos podrán desbloquearse si transcurre más del doble del tiempo de espera.
Cuando un proceso termina de trabajar en un registro, borra el indicador de bloqueo y marca el registro como procesado (otra vez, otro indicador).
Probablemente querrá tener dos campos:uno que almacenaría el indicador de bloqueo de marca de tiempo y otro que indicaría qué proceso posee el bloqueo (en caso de que le interese). Supongo que hay algún tipo de clave que se puede usar para ordenar los registros en la tabla de modo que el concepto de "próxima acción" sea significativo.
Podría usar una consulta como esta para obtener el siguiente registro a procesar:
-- find the next available process and "lock" it by updating it's flag
UPDATE actions_tabe
SET LockFlag = @timestamp,
Process = @processname
WHERE Id IN (SELECT Id
FROM actions_table
WHERE LockFlag IS null
AND IsComplete = '0'
AND ScheduledTime < now()
ORDER BY Scheduledtime ASC, Id ASC
LIMIT 1);
-- return the Id and Action of the record that was just marked above
SELECT Id, Action
FROM actions_table
WHERE Process = @processname
Ejemplo de violín aquí:http://sqlfiddle.com/#!11/9c120/26 /1