From 897eca895a49dfbb53474a9d1b753ee5fce10ee9 Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Thu, 16 Jul 2026 09:32:03 +0530 Subject: [PATCH] fix(stock): fall back gracefully when transaction_advisory_lock is unavailable Same hasattr pattern as repost_gate: an ERPNext ahead of its frappe build keeps the status-quo serialization-failure retries instead of failing every stock submission on postgres. --- erpnext/stock/stock_ledger.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py index e97bbd923ab..aaecd0a4e0c 100644 --- a/erpnext/stock/stock_ledger.py +++ b/erpnext/stock/stock_ledger.py @@ -294,8 +294,10 @@ def sle_processing_gate(item_code, warehouse): gap locks its previous-SLE locking reads take (which also block, then reveal, concurrent inserts); postgres locking reads never see rows another transaction is inserting, so without this gate two concurrent writers compute from the same stale previous SLE and the loser's Bin - write is lost. Txn-scoped and re-entrant; released at commit/rollback.""" - if frappe.db.db_type == "postgres": + write is lost. Txn-scoped and re-entrant; released at commit/rollback. hasattr keeps a frappe + predating transaction_advisory_lock on the status quo (serialization-failure retries) instead + of breaking every stock submission.""" + if frappe.db.db_type == "postgres" and hasattr(frappe.db, "transaction_advisory_lock"): frappe.db.transaction_advisory_lock(("stock-sle", item_code, warehouse), timeout=REPOST_LOCK_TIMEOUT)