python - example - Django-Rollback guardado con transacción atómica
django 2 transaction (2)
Estoy tratando de crear una vista donde guardo un objeto pero me gustaría deshacer ese guardado si se produce alguna excepción. Esto es lo que intenté:
class MyView(View):
@transation.atomic
def post(self, request, *args, **kwargs):
try:
some_object = SomeModel(...)
some_object.save()
if something:
raise exception.NotAcceptable()
# When the workflow comes into this condition, I think the previous save should be undome
# Whant am I missing?
except exception.NotAcceptable, e:
# do something
¿Qué estoy haciendo mal? incluso cuando se levanta la excepción, some_object
sigue en DataBase.
Sin embargo, si ocurre una excepción en una función decorada con transaction.atomic, entonces no tiene nada que hacer, retrocederá automáticamente al punto de salvaguarda creado por el decorador antes de ejecutar su función , según se documenta :
atomic nos permite crear un bloque de código dentro del cual se garantiza la atomicidad en la base de datos. Si el bloque de código se completa con éxito, los cambios se confirman en la base de datos. Si hay una excepción, los cambios se retrotraen.
Si la excepción está atrapada en un bloque de excepción, entonces se debe volver a elevar para que Atomic la atrape y haga la reversión, es decir:
try:
some_object = SomeModel(...)
some_object.save()
if something:
raise exception.NotAcceptable()
# When the workflow comes into this condition, I think the previous save should be undome
# Whant am I missing?
except exception.NotAcceptable, e:
# do something
raise # re-raise the exception to make transaction.atomic rollback
Además, si desea más control, puede retroceder manualmente para establecer el punto de salvaguarda establecido anteriormente , es decir:
class MyView(View):
def post(self, request, *args, **kwargs):
sid = transaction.savepoint()
some_object = SomeModel(...)
some_object.save()
if something:
transaction.savepoint_rollback(sid)
else:
try:
# In worst case scenario, this might fail too
transaction.savepoint_commit(sid)
except IntegrityError:
transaction.savepoint_rollback(sid)
Para resumir, @transaction.atomic
ejecutará una transacción en la base de datos si su vista produce una respuesta sin errores. Como usted mismo está captando la excepción, a Django le parece que su vista se ejecutó bien.
Si detecta la excepción, debe manejarlo usted mismo: Controlling Transactions
Si necesita producir una respuesta json adecuada en caso de fallo:
from django.db import SomeError, transaction
def viewfunc(request):
do_something()
try:
with transaction.atomic():
thing_that_might_fail()
except SomeError:
handle_exception()
render_response()