[英]Django - Rollback save with transaction atomic
我正在尝试创建一个保存对象的视图,但如果出现某些异常,我想撤消该保存。 这是我试过的:
class MyView(View):
@transaction.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 undone
# What am I missing?
except exception.NotAcceptable, e:
# do something
我究竟做错了什么? 即使引发异常, some_object
仍在数据库中。
总而言之,如果您的视图产生无错误的响应, @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()
但是,如果在用 transaction.atomic 装饰的函数中发生异常,那么您无需执行任何操作,它会自动回滚到装饰器在运行您的函数之前创建的保存点,如文档所示:
atomic 允许我们创建一个代码块,其中保证了数据库的原子性。 如果代码块成功完成,更改将提交到数据库。 如果出现异常,则回滚更改。
如果异常在 except 块中被捕获,那么它应该被重新引发以供 atomic 捕获它并进行回滚,即:
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)
对我来说,这适用于 Django 2.2.5
首先在你的 settings.py 中
...
DATABASES = {
'default': {
'ENGINE': 'xxx', # transactional db
...
'ATOMIC_REQUESTS': True,
}
}
在你的函数中(views.py)
from django.db import transaction
@transaction.atomic
def make_db_stuff():
# do stuff in your db (inserts or whatever)
if success:
return True
else:
transaction.set_rollback(True)
return False
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.