【问题标题】:How to pick one element from database atomically?如何从数据库中原子地选择一个元素?
【发布时间】:2014-11-03 14:42:10
【问题描述】:

我有一个带有简单模型的 Django 应用程序:

class ThingToPick(models.Model):
    title = models.CharField(max_length=200)
    start_date = models.DateTimeField('date published', auto_now=True)
    status = models.IntegerField(default=0)
    filedata = models.TextField() 

我的一些观点:

    exec_item = ThingToRun.objects.filter(status=0).order_by('start_date')[0]
    exec_item.status = 1
    exec_item.save()

我需要一些方法来从一个且只有一个并发用户中选择每个 ThingToRun。我知道这是坏了,我该如何修复它?

【问题讨论】:

  • 您是否正在尝试构建类似队列的机制,这就是调度程序?我说对了吗?
  • @Puciek 是的,你猜对了
  • 真的应该使用合适的任务管理器,比如 Celery。
  • @DanielRoseman 你的意思是Database-as-IPC anti-pattern?我计划将来升级到 MQ,但目前这只是一个概念证明。
  • @DanielRoseman 我也在轮询和锤击数据库,这很糟糕。我知道。

标签: python django transactions


【解决方案1】:

您在这里真正想做的不仅仅是挑选一些东西,而是挑选一些东西并将其标记为正在进行中,这样其他人就不会在此期间挑选它。所以你要的方法是select_for_update

exec_item = ThingToRun.objects.select_for_update().filter(status=0).order_by('start_date')[0]
exec_item.status = 1
exec_item.save()
...process exec_item ....

【讨论】:

  • 这里不是竞争条件吗?我没有为我的视图配置任何事务。
  • 是的,您需要在自动提交关闭的块内执行此操作。
猜你喜欢
  • 2015-11-03
  • 1970-01-01
  • 2019-05-31
  • 2023-03-11
  • 2015-10-26
  • 2020-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多