Version de développement
Cette documentation décrit la version « next » (develop), non encore publiée. Pour la version stable, basculez sur « v5 » dans l'en-tête.
Développeurs
Verrous transactionnels dans PostgreSQL
Utiliser frappe.db.transaction_advisory_lock pour prendre un verrou advisory libéré à la fin de la transaction, sur PostgreSQL.
Verrous transactionnels dans PostgreSQL
frappe.db.transaction_advisory_lock prend un verrou advisory que PostgreSQL libère à la fin de la transaction en cours, au commit ou au rollback. Il n'y a pas de libération à écrire. Pour un verrou qui reste tenu après un commit, voir Verrous advisory.
frappe.db.transaction_advisory_lock(key, *, timeout=10)
| Paramètre | Effet |
|---|---|
key | Nom du verrou. Dodock le hache en un entier de 64 bits |
timeout | Attente maximale en secondes. Après ce délai, Dodock lève frappe.QueryTimeoutError |
Caractéristiques :
- Dodock appelle
pg_try_advisory_xact_locktoutes les 0,1 seconde, jusqu'au délai. - Un même processus peut reprendre le verrou dans la même transaction sans blocage.
- PostgreSQL inclut ce verrou dans sa détection des interblocages, comme les verrous de ligne.
Sur MariaDB et SQLite, la méthode lève NotImplementedError. Testez le type de base avant l'appel.
Exemple
Exemple fictif : un contrôleur recalcule un compteur par article. Deux validations simultanées du même article doivent passer l'une après l'autre.
import frappe
def recalculer_compteur(item_code: str):
if frappe.db.db_type == "postgres":
frappe.db.transaction_advisory_lock(f"compteur:{item_code}")
total = frappe.db.count("Stock Ledger Entry", {"item_code": item_code, "is_cancelled": 0})
frappe.db.set_value("Item", item_code, "custom_nb_mouvements", total)
# Le verrou est libéré au commit de la requête, ou au rollback en cas d'erreur.
custom_nb_mouvements est un champ personnalisé de l'exemple. N'appelez pas frappe.db.commit() dans un contrôleur : Dodock valide la transaction à la fin de la requête.
Voir les verrous actifs
SELECT locktype, objid, mode, granted
FROM pg_locks
WHERE locktype = 'advisory';