Django select_for_update
May 5, 2019 · 1 minute read · Commentsprogrammingpython
select_for_update
queryset’de donen rowlar uzerinde ayni anda birden fazla update/delete querysi calismasini engeller.
Asagidaki kodu inceledigimizde ayni anda ayni bayi(Dealer
)‘in bakiyesi guncellenmesini engelliyoruz. Bu acilan DB transactioni bitene kadar ikinci request Dealer
‘in cekildigi satirda bekler.
@transaction.atomic
def post(self, request, **kwargs):
d = Dealer.objects.select_for_update().get(pk=self.kwargs['pk'])
d.balance -= 100
d.save()
...
select_for_update
kullanmadigimiz durumda ayni anda ayni bayi icin bu query calistiginda(bayinin bakiyesinin 1000 oldugunu varsayarsak) ayni anda calistiklari icin islem sonucunda bakiye 800 kalmasi gerekirken 900 kalacaktir.
Bu sebeple update/delete querylerinin calistigi yerlerde transaction’i acar acmaz ilk isimiz update edilecek objeleri select_for_update ile cekmek olmalidir.
Not: Django querysetler lazy oldugu icin query’nin yazildigi satirda degil cekildigi satira gelince obur calisan queryi beklemeye baslayacagini unutmamak lazim.
Not2: select_for_update
eklenmedigi icin olusan hatalari bulmak zordur.