[{"data":1,"prerenderedAt":253},["ShallowReactive",2],{"\u002Fnext\u002Fdodock\u002Fdeveloppeurs\u002Fverrous-transactionnels-postgresql":3,"section:\u002Fnext\u002Fdodock\u002Fdeveloppeurs\u002Fverrous-transactionnels-postgresql":252},{"id":4,"title":5,"body":6,"description":239,"extension":240,"meta":241,"navigation":147,"path":248,"seo":249,"stem":250,"__hash__":251},"docs\u002F2.next\u002F3.dodock\u002F10.developpeurs\u002Fverrous-transactionnels-postgresql.md","Verrous transactionnels dans PostgreSQL",{"type":7,"value":8,"toc":235},"minimark",[9,13,38,54,97,100,117,124,129,132,195,205,209,231],[10,11,5],"h1",{"id":12},"verrous-transactionnels-dans-postgresql",[14,15,16,20,21,24,25,28,29,31,32,37],"p",{},[17,18,19],"code",{},"frappe.db.transaction_advisory_lock"," prend un verrou advisory que PostgreSQL libère à la fin de la transaction en cours, au ",[17,22,23],{},"commit"," ou au ",[17,26,27],{},"rollback",". Il n'y a pas de libération à écrire. Pour un verrou qui reste tenu après un ",[17,30,23],{},", voir ",[33,34,36],"a",{"href":35},"\u002Fnext\u002Fdodock\u002Fdeveloppeurs\u002Fverrous-advisory","Verrous advisory",".",[39,40,45],"pre",{"className":41,"code":42,"language":43,"meta":44,"style":44},"language-python shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","frappe.db.transaction_advisory_lock(key, *, timeout=10)\n","python","",[17,46,47],{"__ignoreMap":44},[48,49,52],"span",{"class":50,"line":51},"line",1,[48,53,42],{},[55,56,57,70],"table",{},[58,59,60],"thead",{},[61,62,63,67],"tr",{},[64,65,66],"th",{},"Paramètre",[64,68,69],{},"Effet",[71,72,73,84],"tbody",{},[61,74,75,81],{},[76,77,78],"td",{},[17,79,80],{},"key",[76,82,83],{},"Nom du verrou. Dodock le hache en un entier de 64 bits",[61,85,86,91],{},[76,87,88],{},[17,89,90],{},"timeout",[76,92,93,94],{},"Attente maximale en secondes. Après ce délai, Dodock lève ",[17,95,96],{},"frappe.QueryTimeoutError",[14,98,99],{},"Caractéristiques :",[101,102,103,111,114],"ul",{},[104,105,106,107,110],"li",{},"Dodock appelle ",[17,108,109],{},"pg_try_advisory_xact_lock"," toutes les 0,1 seconde, jusqu'au délai.",[104,112,113],{},"Un même processus peut reprendre le verrou dans la même transaction sans blocage.",[104,115,116],{},"PostgreSQL inclut ce verrou dans sa détection des interblocages, comme les verrous de ligne.",[14,118,119,120,123],{},"Sur MariaDB et SQLite, la méthode lève ",[17,121,122],{},"NotImplementedError",". Testez le type de base avant l'appel.",[125,126,128],"h2",{"id":127},"exemple","Exemple",[14,130,131],{},"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.",[39,133,135],{"className":41,"code":134,"language":43,"meta":44,"style":44},"import frappe\n\n\ndef recalculer_compteur(item_code: str):\n    if frappe.db.db_type == \"postgres\":\n        frappe.db.transaction_advisory_lock(f\"compteur:{item_code}\")\n\n    total = frappe.db.count(\"Stock Ledger Entry\", {\"item_code\": item_code, \"is_cancelled\": 0})\n    frappe.db.set_value(\"Item\", item_code, \"custom_nb_mouvements\", total)\n    # Le verrou est libéré au commit de la requête, ou au rollback en cas d'erreur.\n",[17,136,137,142,149,154,160,166,172,177,183,189],{"__ignoreMap":44},[48,138,139],{"class":50,"line":51},[48,140,141],{},"import frappe\n",[48,143,145],{"class":50,"line":144},2,[48,146,148],{"emptyLinePlaceholder":147},true,"\n",[48,150,152],{"class":50,"line":151},3,[48,153,148],{"emptyLinePlaceholder":147},[48,155,157],{"class":50,"line":156},4,[48,158,159],{},"def recalculer_compteur(item_code: str):\n",[48,161,163],{"class":50,"line":162},5,[48,164,165],{},"    if frappe.db.db_type == \"postgres\":\n",[48,167,169],{"class":50,"line":168},6,[48,170,171],{},"        frappe.db.transaction_advisory_lock(f\"compteur:{item_code}\")\n",[48,173,175],{"class":50,"line":174},7,[48,176,148],{"emptyLinePlaceholder":147},[48,178,180],{"class":50,"line":179},8,[48,181,182],{},"    total = frappe.db.count(\"Stock Ledger Entry\", {\"item_code\": item_code, \"is_cancelled\": 0})\n",[48,184,186],{"class":50,"line":185},9,[48,187,188],{},"    frappe.db.set_value(\"Item\", item_code, \"custom_nb_mouvements\", total)\n",[48,190,192],{"class":50,"line":191},10,[48,193,194],{},"    # Le verrou est libéré au commit de la requête, ou au rollback en cas d'erreur.\n",[14,196,197,200,201,204],{},[17,198,199],{},"custom_nb_mouvements"," est un champ personnalisé de l'exemple. N'appelez pas ",[17,202,203],{},"frappe.db.commit()"," dans un contrôleur : Dodock valide la transaction à la fin de la requête.",[125,206,208],{"id":207},"voir-les-verrous-actifs","Voir les verrous actifs",[39,210,214],{"className":211,"code":212,"language":213,"meta":44,"style":44},"language-sql shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","SELECT locktype, objid, mode, granted\nFROM pg_locks\nWHERE locktype = 'advisory';\n","sql",[17,215,216,221,226],{"__ignoreMap":44},[48,217,218],{"class":50,"line":51},[48,219,220],{},"SELECT locktype, objid, mode, granted\n",[48,222,223],{"class":50,"line":144},[48,224,225],{},"FROM pg_locks\n",[48,227,228],{"class":50,"line":151},[48,229,230],{},"WHERE locktype = 'advisory';\n",[232,233,234],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":44,"searchDepth":51,"depth":144,"links":236},[237,238],{"id":127,"depth":144,"text":128},{"id":207,"depth":144,"text":208},"Utiliser frappe.db.transaction_advisory_lock pour prendre un verrou advisory libéré à la fin de la transaction, sur PostgreSQL.","md",{"icon":242,"reviewed":147,"last_verified":243,"sources":244},"i-mdi-lock-clock","2026-11-03",[245,246,247],"dodock@develop:frappe\u002Fdatabase\u002Fdatabase.py","dodock@develop:frappe\u002Fdatabase\u002Fpostgres\u002Fdatabase.py","dodock@develop:frappe\u002Ftests\u002Ftest_db.py","\u002Fnext\u002Fdodock\u002Fdeveloppeurs\u002Fverrous-transactionnels-postgresql",{"title":5,"description":239},"2.next\u002F3.dodock\u002F10.developpeurs\u002Fverrous-transactionnels-postgresql","DKcna3gX84p0gfvghvKJXzMydK0lqAEnrtAwu3Dej7c",{},1793871753992]