I am having issues with Django's transaction.atomic. I have this app that users can update their information, but I will be giving an example here using age, but in reality it will be something like an account balance.
So I want to prevent update to this field if more than one requests is received concurrently, so I want to lock the row which is why I am using transaction.atomic and select_for_update. So I have a UserProfile model that I want to update some information, the method which i use to update is below:
Class Profile(models.Model):
def get_queryset(self):
return self.__class__.objects.filter(id=self.id)
@transaction.atomic()
def update_age(
self,
age: int,
) -> None:
obj = self.get_queryset().select_for_update().get()
obj.age = age
obj.save()
Below is the view
class UserProfileView(APIView):
def put(self, request):
profile = rquest.user.profile
profile.update_age(request.data["age"])
UpdateHistory.objects.create(user=request.user, updated_field="age")
The issue is UpdateHistory object is created but the age update is rolled back, but when I remove the creation of the UpdateHistory, the age is updated successfully. So the above code only creates UpdateHistory, but doesn’t update UserProfile.age. But if I remove the line UpdateHistory.objects.create(user=request.user, updated_field="age"), the age is updated successfully.
No exception is being raised at all, this has been confusing me for days. Hopefully I can get some help. Thanks in advance
I would have just used a django
update: