Applez Nous: +41 22 518 70 00
Pour arbitrer les accès concurrents, PostgreSQL utilise une grille complexe de verrous :
ACCESS SHARE (posé par un SELECT ordinaire) au destructeur ACCESS EXCLUSIVE (posé par un ALTER TABLE ou DROP TABLE bloquant toutes les lectures).FOR UPDATE et FOR SHARE permettant de réserver explicitement un tuple avant modification pour éviter les conditions de course (Race Conditions).Un interblocage (deadlock) survient lorsque la Transaction 1 détient un verrou sur la Ligne A et attend un verrou sur la Ligne B, tandis que simultanément la Transaction 2 détient le verrou sur la Ligne B et attend le verrou sur la Ligne A. Aucune des deux ne peut progresser.
-- Transaction 1 (Débit compte A vers B)
BEGIN;
SELECT * FROM comptes WHERE iban = 'CH93-A' FOR UPDATE;
-- En attente du compte B...
UPDATE comptes SET solde_chf = solde_chf + 100 WHERE iban = 'CH93-B';
COMMIT;
-- Transaction 2 (Débit compte B vers A)
BEGIN;
SELECT * FROM comptes WHERE iban = 'CH93-B' FOR UPDATE;
-- En attente du compte A...
UPDATE comptes SET solde_chf = solde_chf + 50 WHERE iban = 'CH93-A';
COMMIT;
PostgreSQL intègre un démon de détection de deadlock (paramétré par deadlock_timeout, 1 seconde par défaut). Il interrompt automatiquement l’une des deux transactions par une exception afin de débloquer le système.
Pour éliminer les deadlocks à la racine au niveau applicatif, appliquez toujours la règle de l’ordonnancement strict : verrouillez systématiquement les ressources dans le même ordre alphabétique ou numérique de clés primaires dans tout votre code.