Django中带有引发异常的transaction.rollback()的正确方法 [英] Correct way of transaction.rollback() with raise exception in django

查看:566
本文介绍了Django中带有引发异常的transaction.rollback()的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Django 1.7.1和python 2.7,正在执行一些需要在事务内的POST请求,实际上我正在使用 @ transaction.atomic()装饰器,使整个函数位于事务内。

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.

据我所知,该装饰器类似于 commit_on_success 并在出现数据库错误时进行回滚。

As far as I know, this decorator is similar to commit_on_success and makes a rollback if a database error is raised.

是否有可能引发使事务回滚但不使用保存点的自定义异常?回滚完成后,我想返回一个HttpResponse,解释为什么事务未完成。

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.

我有这个。

@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:
        ...


推荐答案

在这种情况下-删除装饰器,您可以在视图中包装部分代码:

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()

在handle_exception()中尝试在 atomic 内部进行的任何操作都已经安全地回滚了

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

这篇关于Django中带有引发异常的transaction.rollback()的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆