PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Verrouillage de la ligne de la base de données lors de plusieurs transactions

Votre solution avec le drapeau semble réalisable et je pense que la seule chose nécessaire est de faire expirer le verrou. Fondamentalement, la façon dont je construirais le verrou est d'écrire un horodatage lorsque le verrou a été pris et de faire en sorte que le processus doive mettre à jour le verrou de temps en temps (c'est-à-dire toutes les 30 secondes) pendant qu'il travaille encore sur l'enregistrement. Si le processus meurt ou ne parvient pas à terminer le travail, le verrou expirera et d'autres processus pourront se déverrouiller si plus du double du délai d'expiration s'est écoulé.

Lorsqu'un processus termine de travailler sur un enregistrement, il efface l'indicateur de verrouillage et marque l'enregistrement comme traité (encore un autre indicateur).

Vous voudrez probablement avoir deux champs :un qui stockerait l'indicateur de verrouillage d'horodatage et un autre qui indiquerait quel processus possède le verrou (au cas où cela vous intéresserait). Je suppose qu'il existe une sorte de clé qui peut être utilisée pour ordonner les enregistrements dans la table de sorte que le concept d'"action suivante" soit significatif.

Vous pouvez utiliser une requête comme celle-ci pour obtenir le prochain enregistrement à traiter :

 -- 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

Exemple de violon ici :http://sqlfiddle.com/#!11/9c120/26 /1