Correct way of transaction.rollback() with raise exception in django
Solution 1
In this case - remove decorator, you can wrap part of code in your view:
try:
with transaction.atomic():
# ...
if mal != '':
raise IntegrityError
except IntegrityError:
handle_exception()
Any operations attempted inside atomic
will already have been rolled back safely when handle_exception() is called.
https://docs.djangoproject.com/en/dev/topics/db/transactions/#django.db.transaction.atomic
Solution 2
I have configured my db to 'ATOMIC_REQUESTS'
, so each request is also nested in a transaction.
I was looking for a way to rollback without raising an exception. I know, that's not the original question, but for the record the following worked (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
Alex Lord Mordor
Updated on August 22, 2020Comments
-
Alex Lord Mordor almost 4 years
I am working with Django 1.7.1 and python 2.7, I am doing some POST requests that requires to be inside a transaction, actually I am using
@transaction.atomic()
decorator that makes the entire function to be inside a transaction.As far as I know, this decorator is similar to
commit_on_success
and makes a rollback if a database error is raised.Is it possible to raise a custom exception that makes the transaction to rollback but not using save points? I want to return a HttpResponse when the rollback is done, explaining why the transaction was not completed.
I have this.
@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: ...