test(extras): Release the data lock explicitly

Closing the helper's connection does not wait for PostgreSQL to release
its session advisory lock, so the deletion which follows could still see
the lock held and abort. Release it with pg_advisory_unlock() instead.

Fixes #23145
This commit is contained in:
Martin Hauser 2026-09-07 21:43:21 +02:00
parent c9a62254d7
commit 7d124a2b1b
No known key found for this signature in database
1 changed files with 12 additions and 3 deletions

View File

@ -2876,9 +2876,18 @@ def hold_data_lock(custom_field):
cursor.execute('SELECT pg_try_advisory_lock(%s, %s)', lock_key)
if not cursor.fetchone()[0]:
raise RuntimeError(f"Failed to acquire the data lock for {custom_field}")
yield
released = False
try:
yield
finally:
# Closing the connection releases the lock asynchronously, so the next deletion can race it
with connection.cursor() as cursor:
cursor.execute('SELECT pg_advisory_unlock(%s, %s)', lock_key)
released = cursor.fetchone()[0]
# Outside the finally, so a failing body is reported as itself
if not released:
raise RuntimeError(f"Failed to release the data lock for {custom_field}")
finally:
# Closing the session releases any advisory lock held on it
connection.close()
@ -3739,7 +3748,7 @@ class DeferredCustomFieldDataTestCase(TestCase):
# delete() has returned and its own atomic block has exited, but the enclosing transaction
# has yet to commit, so the lock must still be held
with self.assertRaises(RuntimeError):
with self.assertRaisesMessage(RuntimeError, "Failed to acquire the data lock"):
with hold_data_lock(cf):
pass