该应用程序具有以下相关模型:公司,节点和日志。
class VCompany(models.Model):
company_name = models.CharField(max_length=50, ...)
class VNode(models.Model):
company = models.ForeignKey(VCompany, ...)
name1 = models.CharField(...)
name2 = models.CharField(...)
class Log(models.Model):
node = models.ForeignKey(VNode, ... )
VNode必须是唯一的。不幸的是,没有简单的唯一/唯一在一起。如果name1是已知的,则company和name1的组合是唯一的。如果name2是已知的,则company和name2的组合是唯一的。name1或name2或两者都是已知的。
问题1:是否可以为上述情况构造一个唯一子句?如何?
芹菜任务用于通过处理文件中的某些数据来在日志中创建记录。有许多芹菜任务同时运行以创建日志记录。创建日志记录后,可能需要创建一个vnode。这将导致创建重复的vnode记录。为了解决这个问题,我正在这样做:
with transaction.atomic():
# Get the company for update as a sync method.
company = VCompany.objects.select_for_update().get(company_name=company)
if name1:
node, create = VNode.objects.get_or_create(company=company, name1=... )
... set other node data ...
node.save()
return node
if name2:
node, create = VNode.objects.get_or_create(company=company, name2=... )
... set other node data ...
node.save()
return node
此代码显然有效。但是,如果我删除带有transaction.atomic()的文件,它肯定会失败。
问题2:为什么需要transaction.atomic()?需要吗?
问题3:django的ORM何时发布select_for_update?是get_or_create导致它在创建新节点之前释放,从而导致出现竞争状况?
感谢您提供任何线索!
问题1:我不知道
问题2:
需要transaction_atomic,因为select_for_update仅在当前事务的持续时间内保持锁定。否则,(如果您未进行任何其他交易)它将立即释放锁。
问题3:
当前事务关闭(提交或回滚)时,将释放该锁。
get_or_create不是原子的,只有在数据库具有正确的唯一性约束时才是线程安全的。如果get_or_create违反唯一性约束,则将引发IntegrityError。
在您的情况下,锁定VCompany应该使VNode上的get_or_create方法无法失败。但是,只有在您正确锁定尝试创建VNode对象的所有位置时,这才是正确的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句