PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Bloqueio de linha do banco de dados durante várias transações


Sua solução com o sinalizador parece viável e acho que a única coisa necessária é fazer o bloqueio expirar. Basicamente, a maneira como eu arquitetaria o bloqueio seria escrever um carimbo de data e hora quando o bloqueio foi feito e fazer com que o processo tivesse que atualizar o bloqueio de vez em quando (ou seja, a cada 30 segundos) enquanto ainda está trabalhando no registro. Se o processo morrer ou falhar em concluir o trabalho, o bloqueio expirará e outros processos poderão desbloquear se mais do que o dobro do período de tempo limite decorrido.

Quando um processo termina de trabalhar em um registro, ele limpa o sinalizador de bloqueio e marca o registro como processado (novamente outro sinalizador).

Você provavelmente desejará ter dois campos:um que armazenaria o sinalizador de bloqueio de carimbo de data e hora e outro que indicaria qual processo possui o bloqueio (caso você se importe com isso). Estou assumindo que existe algum tipo de chave que pode ser usada para ordenar os registros na tabela de forma que o conceito de "próxima ação" seja significativo.

Você pode usar uma consulta como esta para obter o próximo registro a ser processado:
 -- 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

Exemplo de violino aqui:http://sqlfiddle.com/#!11/9c120/26 /1