[WEB-4440] fix: duplicate sequence when creating multiple workitems in rapid succession (#8298)
- Replace advisory lock with transaction-level lock in Issue model save method - Updated the save method in the Issue model to use a transaction-level advisory lock for better concurrency control. - Simplified the locking mechanism by removing the explicit unlock step, as the lock is automatically released at the end of the transaction. - Maintained existing functionality for sequence and sort order management while improving code clarity.
This commit is contained in:
parent
e20f686398
commit
647813a6ab
1 changed files with 22 additions and 26 deletions
|
|
@ -207,15 +207,15 @@ class Issue(ProjectBaseModel):
|
|||
|
||||
if self._state.adding:
|
||||
with transaction.atomic():
|
||||
# Create a lock for this specific project using an advisory lock
|
||||
# Create a lock for this specific project using a transaction-level advisory lock
|
||||
# This ensures only one transaction per project can execute this code at a time
|
||||
# The lock is automatically released when the transaction ends
|
||||
lock_key = convert_uuid_to_integer(self.project.id)
|
||||
|
||||
with connection.cursor() as cursor:
|
||||
# Get an exclusive lock using the project ID as the lock key
|
||||
cursor.execute("SELECT pg_advisory_lock(%s)", [lock_key])
|
||||
# Get an exclusive transaction-level lock using the project ID as the lock key
|
||||
cursor.execute("SELECT pg_advisory_xact_lock(%s)", [lock_key])
|
||||
|
||||
try:
|
||||
# Get the last sequence for the project
|
||||
last_sequence = IssueSequence.objects.filter(project=self.project).aggregate(
|
||||
largest=models.Max("sequence")
|
||||
|
|
@ -236,10 +236,6 @@ class Issue(ProjectBaseModel):
|
|||
super(Issue, self).save(*args, **kwargs)
|
||||
|
||||
IssueSequence.objects.create(issue=self, sequence=self.sequence_id, project=self.project)
|
||||
finally:
|
||||
# Release the lock
|
||||
with connection.cursor() as cursor:
|
||||
cursor.execute("SELECT pg_advisory_unlock(%s)", [lock_key])
|
||||
else:
|
||||
# Strip the html tags using html parser
|
||||
self.description_stripped = (
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue