2016-01-11 15 views
7

Я пытаюсь создать представление, в котором я сохраняю объект, но я хочу, чтобы отменить, которые сохраняются, если возникает какое-то исключение. Это то, что я пробовал:Django - откат с транзакцией Atom

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 

Что я делаю неправильно? даже при возникновении исключения some_object по-прежнему находится в базе данных.

ответ

11

Atomicity Documentation

Резюмируя, @transaction.atomic выполнит транзакцию в базе данных, если ваше представление вызывает ответ без ошибок. Поскольку вы сами выбираете исключение, Django кажется, что ваше представление выполнено просто отлично.

Если вы ловите исключение, вы должны справиться сами: Controlling Transactions

Если вам необходимо произвести надлежащий ответ JSon в случае выхода из строя:

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

Это представление относится к API, поэтому я думаю, что мне нужно обработать любую возможную ошибку, чтобы дать ответ jpper json. Нельзя ли сделать это с помощью атомного декоратора? – Gocht

+0

Не с декоратором imho, потому что он обрабатывает транзакцию вне вашей функции. Приятный пример с менеджером контекста! – jpic

+0

У вас должен быть атомный блок внутри try .. кроме блока, как в ответе. Вы также можете использовать атомный декоратор на экране, если хотите. – Alasdair

5

Однако, если исключение происходит в функции украшенной transaction.atomic, то вам не нужно ничего делать, это будет rollback automatically to the savepoint created by the decorator before running the your function как documented:

атомное позволяет создать блок кода, в котором гарантируется атомарность базы данных. Если блок кода успешно завершен, изменения привязаны к базе данных. Если есть исключение, изменения отбрасываются.

Если исключение пойманный в за исключением блока, то он должен быть вновь поднят на атомный, чтобы поймать его и сделать откат, т.е. .:

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 

Кроме того, если вы хотите больший контроль , вы можете откатить вручную previously set savepoint, т.е. .:

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) 
+0

Вот что я, хотя, и это почему я сделал эту функцию таким образом, но, как я сказал в вопросе, объект все еще находится в событии базы данных, когда возникает исключение, есть ли какой-либо дополнительный шаг для использования точек сохранения? – Gocht

+0

Возможно, это связано с тем, что исключение было уловлено блоком исключения, а не ре-рейзом, поэтому атомал считал, что функция выполнена с успехом. – jpic

+0

Если я не поймаю ошибку, я не могу дать хороший ответ. Как я могу построить свою функцию? – Gocht

 Смежные вопросы

  • Нет связанных вопросов^_^