我有一个简单的图书馆应用程序。为了强制将 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
放在事务之外),但您绝对不应该设置 自动提交=假
。
作为documentation状态,当你想“禁用 Django 的事务管理”时,你可以将该系统范围的设置设置为 False,但这显然不是你想要做的,因为你使用transaction.atomic()!更多来自documentation :
If you do this, Django won’t enable autocommit, and won’t perform any commits. You’ll get the regular behavior of the underlying database library. This requires you to commit explicitly every transaction, even those started by Django or by third-party libraries. Thus, this is best used in situations where you want to run your own transaction-controlling middleware or do something really strange.
所以不要这样做。 Django 当然会禁用该原子 block 的自动提交,并在该 block 完成时重新启用它。
关于python - 控制 Django 中的原子事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37795302/