我正在尝试创建一个保存对象的视图,但是如果引发一些异常,我想撤消该保存.这是我试过的:
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
仍然在DataBase中.
原子文档
总而言之,@transaction.atomic
如果您的视图产生没有错误的响应,将在数据库上执行事务.因为你自己正在捕获异常,所以Django认为你的视图执行得很好.
如果您发现异常,则需要自己处理:控制事务
如果您在发生故障时需要生成适当的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()
但是,如果一个例外饰有transaction.atomic功能情况,那么你没有什么做的,它会自动回滚到运行在你的函数之前,由装饰创建保存点,为记录:
atomic允许我们创建一个代码块,在该代码块中保证数据库的原子性.如果代码块成功完成,则更改将提交到数据库.如果存在异常,则回滚更改.
如果在except块中捕获异常,则应该重新引发异常以捕获它并执行回滚,即:
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
此外,如果您想要更多控制,您可以手动回滚到先前设置的保存点,即:
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)