【发布时间】:2015-11-18 01:11:31
【问题描述】:
我有以下受竞争条件约束的(转述)代码:
def calculate_and_cache(template, template_response):
# run a fairly slow and intensive calculation:
calculated_object = calculate_slowly(template, template_response)
cached_calculation = Calculation(calculated=calculated_object,
template=template,
template_response=template_response)
# try to save the calculation just computed:
try:
cached_calculation.save()
return cached_calculation
# if another thread beat you to saving this, catch the exception
# but return the object that was just calculated
except DatabaseError as error:
log(error)
return cached_calculation
它引发了 DatabaseTransactionError:
TransactionManagementError: An error occurred in the current transaction.
You can't execute queries until the end of the 'atomic' block.
The docs 对 DTE 有这样的看法:
退出原子块时,Django 会查看它是正常退出还是异常退出,以确定是提交还是回滚....如果您尝试在回滚发生之前运行数据库查询,Django 将引发一个 TransactionManagementError。
但是they 也有这个,关于他们还有更模糊的说法:
TransactionManagementError 是针对与数据库事务相关的所有问题引发的。
我的问题,按一般性升序排列:
- 捕获
DatabaseError是否会通过让save()在返回对象的同时优雅退出来真正解决竞争条件? - 上述代码中的原子块从哪里开始,又在哪里结束?
- 我做错了什么,我该如何解决?
【问题讨论】:
标签: python django django-orm