ayarlamadan zaman, üst cevabı kesinlikle en iyi bahis sayacın değerini bilmek gerekir yoksa:
counter = Counter.objects.get_or_create(name = name)
counter.count = F('count') + 1
counter.save()
Bu söyler senin veritabanı, diğer işlemleri engellemeden mükemmel bir şekilde yapabileceği count
değerine 1 ekleyecektir. Bunun dezavantajı, yeni ayarlanmış olan count
'un ne olduğunu bilmenin bir yolu olmamasıdır. İki iş parçacığı eşzamanlı olarak bu işleve basarsa, ikisi de aynı değeri görür ve her ikisi de db'yi 1'e eklemesini söyler. Db beklendiği gibi 2 ekleyerek sona erer, ancak hangisinin ilk başladığını bilemezsiniz.
Şu anda sayımla ilgileniyorsanız, Emil Stenstrom tarafından başvurulan select_for_update
seçeneğini kullanabilirsiniz.
from models import Counter
from django.db import transaction
@transaction.atomic
def increment_counter(name):
counter = (Counter.objects
.select_for_update()
.get_or_create(name=name)[0]
counter.count += 1
counter.save()
Bu akım değeri ve hareket sonuna kadar satır eşleşen kilitleri okur: İşte böyle böyle görünüyor budur. Artık sadece bir işçi bir anda okuyabiliyor. Select_for_update hakkında daha fazla bilgi için bkz. the docs.
Hangi veritabanını kullanıyorsunuz? –
Bana göre yarış koşullarından kaçınmak için '+ =' kullanmama gibi bir israfa benziyor. Python kullanıcıları zaten 'a + = b' ve' a = a + b' arasında bir fark olduğunu bilmeli, bu yüzden neden kullanmıyorsunuz? Belki bazı önbellek verileriyle çakışır mı? Emin değil. – aliqandil