I am building a "poor man's queuing system" using MySQL. It's a single table containing jobs that need to be executed (the table name is queue
). I have several processes on multiple machines whose job it is to call the fetch_next2
sproc to get an item off of the queue.
The whole point of this procedure is to make sure that we never let 2 clients get the same job. I thought that by using the SELECT .. LIMIT 1 FOR UPDATE
would allow me to lock a single row so that I could be sure it was only updated by 1 caller (updated such that it no longer fit the criteria of the SELECT
being used to filter jobs that are "READY" to be processed).
Can anyone tell me what I'm doing wrong? I just had some instances where the same job was given to 2 different processes so I know it doesn't work properly. :)
CREATE DEFINER=`masteruser`@`%` PROCEDURE `fetch_next2`()
BEGIN
SET @id = (SELECT q.Id FROM queue q WHERE q.State = 'READY' LIMIT 1 FOR UPDATE);
UPDATE queue
SET State = 'PROCESSING', Attempts = Attempts + 1
WHERE Id = @id;
SELECT Id, Payload
FROM queue
WHERE Id = @id;
END