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:
parent
c9a62254d7
commit
7d124a2b1b
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue