2017-01-22 8 views
0

ich diese Situation in einer Django REST Framework-Anwendung habe:Django Potential kritische Abschnitt

Ich habe eine Ansicht löschen:

def delete(self, request, pk, lid=None, *args, **kwargs): 

    user_info = self.get_object(pk) 
    if user_info: 
     location = Location.objects.filter(loc_id=lid).first() 
     location.users.remove(user_info) 
     if location.users.count() is 0: 
      //delete location 

     return Response(status=status.HTTP_200_OK) 

    return Response(status=status.HTTP_404_NOT_FOUND) 

Ich denke, dass in diesem Code ein potenzieller kritischer Abschnitt befindet sich:

  • flow - 1: Prüfanzahl Standort Benutzer -> count 0

  • flow - 2: Hinzufügen neuer Benutzer (Benutzer2) in Position Benutzer (durch andere Ansicht)

  • flow - 1: den Standort entfernen, weil Standort Benutzer 0 ist (aber das ist nicht richtig, weil Fluss -2 hat eine neue user_info hinzugefügt.

Ist es möglich, in Django diesen Abschnitt zu haben (Prüfwert und Löschoperation)

location = Location.objects.filter(loc_id=lid).first() 
location.users.remove(user_info) 
if location.users.count() is 0: 
    //delete location 

atomar?

Antwort

0

Nur eine Transaktion verwenden und machen die DB die Situs von atomicity:

Atomicity ist die definierende Eigenschaft von Datenbanktransaktionen. atomic ermöglicht es uns, einen Codeblock zu erstellen, in dem die Atomarität in der Datenbank garantiert ist. Wenn der Codeblock erfolgreich abgeschlossen wurde, werden die Änderungen an die Datenbank übergeben. Wenn eine Ausnahme vorliegt, werden die Änderungen rückgängig gemacht.


from django.db import transaction 

def delete(self, request, pk, lid=None, *args, **kwargs): 
    with transaction.atomic(): 
     user_info = self.get_object(pk) 
     if user_info: 
      location = Location.objects.filter(loc_id=lid).first() 
      location.users.remove(user_info) 
      if location.users.count() is 0: 
       # delete location 
       location.delete() 
      return Response(status=status.HTTP_200_OK) 

     return Response(status=status.HTTP_404_NOT_FOUND)