Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Consumidor produtor do MySQL com vários threads selecionados


Tenho uma solução prática para você, que vi implementada em um projeto no meu local de trabalho. Em vez de usar apenas 0 e 1 para incompletos e concluídos, expanda seu conjunto para incluir mais casos.

Vamos chamar essa coluna de status . Aqui estão os diferentes valores dessa coluna e os estados correspondentes do trabalho.
  1. Quando o status é 0, o trabalho não foi selecionado por nenhum thread de trabalho.
  2. Quando o status é 1, o trabalho foi selecionado por um thread de trabalho e está em processo.
  3. Quando o status é 2, o trabalho falhou. (Você deve considerar a possibilidade de falha no processamento.)
  4. Quando o status é 3, o trabalho foi concluído.

Seus encadeamentos devem conter uma lógica de modo que apenas pegue os trabalhos para quem o status é 0 e altere o status para 1. Isso não permitirá que outros encadeamentos peguem os trabalhos que estão em processo. Quando o trabalho é concluído, o status é definido como 3 e, se o trabalho falhar, o status é definido como 2. Em seguida, o encadeamento pode seguir em frente e procurar outro trabalho que ainda não foi concluído.

Você também pode pedir aos encadeamentos que considerem pegar trabalhos de status 2, mas você terá que definir a lógica para especificar um número finito de tentativas.

EDITAR:

Após uma longa discussão , encontramos a solução juntos. Minha resposta acima é boa em um estado mais generalizado quando o 'trabalho' é um processo que leva algum tempo para ser concluído. Mas esse não foi o caso do problema do OP.

Então, a solução que acabou funcionando foi esta:
BEGIN 
SELECT * FROM Jobs WHERE JobID = (SELECT * FROM Jobs WHERE completed = 0 LIMIT 1) LOCK IN SHARE MODE;
UPDATE Jobs SET completed = 1 WHERE JobID = (PREVIOUS ID); 
COMMIT;