Ho bisogno di assicurarmi che un oggetto letto dal database e riscritto, non possa essere modificato nel frattempo da un'altra richiesta/processo.Django transaction.atomic() garantisce atomico READ + WRITE?
Does transaction.atomic() lo garantisce?
Le mie prove finora mi dicono no. Se non c'è niente di sbagliato in loro, quale sarebbe il modo giusto per ottenere LETTURE e SCRITTURE atomici?
Il mio esempio che ho provato.
Mettere il Test classe da qualche parte nel modello. atomic_test.py e atomic_test2.py devono essere salvati come comandi di gestione. Esegui python manage.py atomic_test prima, quindi python manage.py atomic_test2. Il secondo script non si blocca e le sue modifiche vengono perse.
models.py
class Test(models.Model):
value = models.IntegerField()
atomic_test.py
from django.core.management.base import NoArgsCommand
from django.db import transaction
from time import sleep
from core.models import Test
class Command(NoArgsCommand):
option_list = NoArgsCommand.option_list
def handle(self, **options):
Test.objects.all().delete()
t = Test(value=50)
t.save()
print '1 started'
with transaction.atomic():
t = Test.objects.all()[0]
sleep(10)
t.value = t.value + 10
t.save()
print '1 finished: %s' %Test.objects.all()[0].value
atomic_test2.py
from django.core.management.base import NoArgsCommand
from django.db import transaction
from time import sleep
from core.models import Test
class Command(NoArgsCommand):
option_list = NoArgsCommand.option_list
def handle(self, **options):
print '2 started'
with transaction.atomic():
t = Test.objects.all()[0]
t.value = t.value - 20
t.save()
print '2 finished: %s' %Test.objects.all()[0].value
Grazie, è andato con 'select_for_update'. Sembra buono finora. Il valore finale dovrebbe essere 40 (50 + 10-20). – kev