</>
Plan du cours — 57/64

Idempotence et exécutions multiples

Avancé

Dans un système distribué, tout message et toute requête peuvent être livrés plus d'une fois : les traitements doivent l'accepter.

Table de messages traités#

CREATE TABLE messages_traites (
    id_message  text PRIMARY KEY,
    traite_le   timestamptz NOT NULL DEFAULT now()
);

BEGIN;
INSERT INTO messages_traites (id_message) VALUES ($1) ON CONFLICT DO NOTHING;
-- Si 0 ligne insérée : déjà traité, on s'arrête (COMMIT et retour).
-- Sinon : effectuer le traitement métier dans la même transaction.
COMMIT;

L'enregistrement du message et l'effet métier sont atomiques : soit les deux, soit aucun.

Verrous consultatifs#

Pour qu'une seule instance exécute une tâche planifiée à la fois (sans dépendre d'un composant externe) :

SELECT pg_try_advisory_lock(hashtext('rapport-quotidien'));    -- true si le verrou est obtenu
-- ... travail ...
SELECT pg_advisory_unlock(hashtext('rapport-quotidien'));

pg_advisory_xact_lock libère automatiquement le verrou à la fin de la transaction, ce qui convient aussi derrière un pooleur en mode transaction.