diff --git a/api/features/models.py b/api/features/models.py index 43ab7f986bbb..afb7f69637dd 100644 --- a/api/features/models.py +++ b/api/features/models.py @@ -13,7 +13,7 @@ ObjectDoesNotExist, ValidationError, ) -from django.db import models +from django.db import models, transaction from django.db.models import Max, Q, QuerySet from django.utils import formats, timezone from django_lifecycle import ( # type: ignore[import-untyped] @@ -216,6 +216,8 @@ def _get_project(self) -> typing.Optional["Project"]: def get_next_segment_priority(feature): # type: ignore[no-untyped-def] + Feature.objects.select_for_update().get(pk=feature.id) + feature_segments = FeatureSegment.objects.filter(feature=feature).order_by( "-priority" ) @@ -281,6 +283,14 @@ class FeatureSegment( objects = FeatureSegmentManager() # type: ignore[misc] + @hook(BEFORE_CREATE) + def set_priority(self) -> None: + if self.priority is None: + # We use an atomic transaction here to ensure + # the select_for_update() lock in get_next_segment_priority works. + with transaction.atomic(): + self.priority = get_next_segment_priority(self.feature) + class Meta: unique_together = ( "feature",