From 430f974db1acab7da79075e89a0f727223ee7fb4 Mon Sep 17 00:00:00 2001 From: Dan LaManna Date: Mon, 10 Nov 2025 17:06:09 -0500 Subject: [PATCH] Use a more exclusive lock for publishing tables This was leading to quite reproducible deadlocks during publish. When the table is locked for share mode and two concurrenct transactions acquire the lock, t1 acquires a row exclusive lock on IsicId creation and waits for t2 that's just been opened in share mode to complete. When t2 then attempts to acquire a row exclusive lock to create an IsicId - t2 deadlocks because it recognizes that it's now waiting for t1. This modifies the code such that an exclusive lock is acquired, and reads are the only operations that can happen concurrently. This makes it such that every accession_publish call is effectively serialized. --- isic/core/utils/db.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/isic/core/utils/db.py b/isic/core/utils/db.py index 27ad5a492..74a1d473e 100644 --- a/isic/core/utils/db.py +++ b/isic/core/utils/db.py @@ -7,7 +7,7 @@ def lock_table_for_writes(cls: type[models.Model]): with transaction.atomic(): cursor = transaction.get_connection().cursor() - cursor.execute(f"LOCK TABLE {cls._meta.db_table} IN SHARE MODE") + cursor.execute(f"LOCK TABLE {cls._meta.db_table} IN EXCLUSIVE MODE") try: yield finally: