O que você precisa fazer é adicionar algum tipo de bloqueio aqui para evitar condições de corrida como a que você criou:
UPDATE persons SET processing=1 WHERE id=:id AND processing=0
Isso evitará o travamento duplo.
Para melhorar ainda mais, crie uma coluna de bloqueio que você pode usar para reivindicar:
UPDATE persons
SET processing=:processing_uuid
WHERE processing IS NULL
LIMIT 1
Isso requer um
VARCHAR
, processing
indexado coluna usada para reivindicar que tem um padrão de NULL
. Se você obtiver uma linha modificada nos resultados, você reivindicou um registro e pode trabalhar com ele usando:SELECT * FROM persons WHERE processing=:processing_uuid
Cada vez que você tentar reivindicar, gere uma nova chave UUID de reivindicação.