Primeiro: o MySQL é um dos piores softwares possíveis para implementar isso, especialmente se for muito dinâmico. O motivo é que mecanismos como MEMORY e MyISAM têm apenas bloqueios de tabela completa, enquanto mecanismos mais adequados, como o InnoDB, têm uma penalidade de gravação mais alta (para fornecer propriedades ACID) e são otimizados para acessar registros que estão próximos espacial e temporalmente (aqueles configurados na memória ) Também não existe um bom sistema de notificação de alterações para o MySQL - ele deve ser implementado como uma pesquisa. Existem dezenas de softwares mais otimizados para essa tarefa .
Dito isto, vi implementar com êxito esse tipo de acesso se os requisitos de desempenho / eficiência não forem muito altos. Muitas pessoas não podem se dar ao luxo de introduzir e manter uma peça completa de tecnologia separada apenas por uma pequena parte da lógica de negócios.
SELECT FOR UPDATE
é o que você está procurando - ler serialização. Enquanto um UPDATE / DELETE sempre bloqueia a linha durante uma transação MYSQL em execução, convém evitar uma transação grande enquanto o processo está em andamento, portanto:
START TRANSACTION;
SELECT * FROM your_table WHERE state != 'PROCESSING'
ORDER BY date_added ASC LIMIT 1 FOR UPDATE;
if (rows_selected = 0) { //finished processing the queue, abort}
else {
UPDATE your_table WHERE id = $row.id SET state = 'PROCESSING'
COMMIT;
// row is processed here, outside of the transaction, and it can take as much time as we want
// once we finish:
DELETE FROM your_table WHERE id = $row.id and state = 'PROCESSING' LIMIT 1;
}
O MySQL cuidará do bloqueio de todas as seleções simultâneas, exceto uma ao selecionar linhas. Como isso pode levar a muitas conexões bloqueadas ao mesmo tempo, mantenha a transação inicial o menor possível e tente processar mais de uma linha por vez.