[英]Control Atomic Transactions in Django
我有一个简单的库应用程序。 为了强制3个动作作为一个动作提交,并且如果任何动作失败则回滚,我做了以下代码更改:
在settings.py
:
AUTOCOMMIT=False
在forms.py
from django.db import IntegrityError, transaction
class CreateLoan(forms.Form):
#Fields...
def save(self):
id_book = form.cleaned_data.get('id_book', None)
id_customer = form.cleaned_data.get('id_customer', None)
start_date = form.cleaned_data.get('start_date', None)
book = Book.objects.get(id=id_book)
customer = Customer.objects.get(id=id_customer)
new_return = Return(
book=book
start_date=start_date)
txn=Loan_Txn(
customer=customer,
book=book,
start_date=start_date
)
try
with transaction.atomic():
book.update(status="ON_LOAN")
new_return.save(force_insert=True)
txn.save(force_insert=True)
except IntegrityError:
raise forms.ValidationError("Something occured. Please try again")
我还有什么遗漏吗? 我正在使用Django 1.9和Python 3.4.3,数据库是MySQL。
你正确地使用了transaction.atomic()
(包括把try ... except
放在事务之外)但是你绝对不应该设置AUTOCOMMIT = False
。
正如文档所述,当你想要“禁用Django的事务管理”时,你将系统范围的设置设置为False
- 但这显然不是你想要做的,因为你正在使用transaction.atomic()
! 更多来自文档 :
如果你这样做,Django将不会启用自动提交,并且不会执行任何提交。 您将获得底层数据库库的常规行为。 这要求您明确提交每个事务,甚至是由Django或第三方库启动的事务。 因此,这最适用于您想要运行自己的事务控制中间件或做一些非常奇怪的事情的情况。
所以就是不要这样做。 Django当然会禁用该原子块的自动提交,并在块完成时重新启用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.