Goc*_*cht 27 python django transactions atomicity django-database
我正在尝试创建一个保存对象的视图,但是如果引发一些异常,我想撤消该保存.这是我试过的:
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
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?即使引发异常some_object仍然在DataBase中.
jlu*_*ier 34
总而言之,@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()
Run Code Online (Sandbox Code Playgroud)
jpi*_*pic 14
但是,如果一个例外饰有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
Run Code Online (Sandbox Code Playgroud)
此外,如果您想要更多控制,您可以手动回滚到先前设置的保存点,即:
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)
Run Code Online (Sandbox Code Playgroud)
对我来说,这适用于 Django 2.2.5
首先在你的settings.py
...
DATABASES = {
'default': {
'ENGINE': 'xxx', # transactional db
...
'ATOMIC_REQUESTS': True,
}
}
Run Code Online (Sandbox Code Playgroud)
在你的函数中(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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
39011 次 |
| 最近记录: |