Correct way to transaction.rollback () with throwing exception in django

I am working with Django 1.7.1 and python 2.7, I am making several POST requests that need to be inside a transaction, in fact I am using a @transaction.atomic()

decorator that does the whole function inside a transaction.

As far as I know, this decorator is similar to commit_on_success

and does rollback when a database error occurs.

Is it possible to throw a custom exception that rolls back a transaction but doesn't use savepoints? I want to return an HttpResponse when a rollback is in progress explaining why the transaction was not completed.

I have it.

@transaction.atomic()
def salida_de_almacen(request):
    if request.method == 'POST':
        try:
            folio = request.POST['folio'] #Folio de la orden
            epccoma = request.POST['epc'] #EPCs separados por coma
            if folio is None or epccoma is None:
                return HttpResponse('Datos Incompletos',status=400)
            detalles = ODetalle.objects.filter(orden__folio=folio)
            epcs = epccoma.replace(' ','').split(',')
            inventario = Inventario.objects.filter(epc__in=epcs)
            mal = '' # Items incompletos
            for d in detalles:
                for i in inventario:
                    if i.producto.item == d.producto.item:
                        d.cantidad_entregada+=i.cantidad                        
                        i.delete()
                if d.cantidad_entregada<d.cantidad_ordenada:
                    mal+='%s,' % d.producto.item
            if mal != '':

         >>>>   #raise Exception??  <<<<---- I WANT TO RISE AN EXCEPTION HERE TO ROLLBACK THE TR. 

                return HttpResponse('Items Incompletos: '+mal,status=400)
            for d in detalles:
                d.status=2 #Status completo
                d.save()
            return HttpResponse(serial_folio,status=200) # Todo bien
        except Exception as e:
            return  HttpResponse(e.message,status=500)    
    else:
        ...

      

+5


source to share


2 answers


In this case - remove the decorator, you can wrap some of the code in your view:

try:
    with transaction.atomic():
        # ...
        if mal != '':
            raise IntegrityError

except IntegrityError:
    handle_exception()

      



Any operations taken internally atomic

will already be safely discarded by calling handle_exception ().

https://docs.djangoproject.com/en/dev/topics/db/transactions/#django.db.transaction.atomic

+10


source


I set my db to 'ATOMIC_REQUESTS'

so every request is nested within a transaction too.

I was looking for a way to rollback without throwing an exception. I know not the original question, but the following worked for the record (django 1.11):



from django.db import transaction

def my_view(request):
    # some db interactions
    if it_hit_the_fan:
        transaction.set_rollback(True)
    # return response

      

0


source







All Articles