我将 MySQL 与 InnoDB 引擎和 REPEATABLE-READ 隔离级别一起使用。

我写了一个函数,我认为它应该原子地递增一个 IntegerField,并在递增后给我值。我想就我的代码是否对并发问题健壮发表意见。

我的代码如下所示:

class MyModel(models.Model):
  version = models.IntegerField()

  @staticmethod
  @transaction.commit_on_success
  def acquire_version(pk):
    MyModel.objects.filter(pk = pk).update(version = F('version') + 1)
    return MyModel.objects.get(pk = pk).version

我的想法是,在两个并发调用中,UPDATE 会因为写锁而相互排斥,然后 REPEATABLE-READ 应该保证我的后续 .get 会在 UPDATE 后给我值。我对吗?

(这不是一般的“我如何进行原子增量?”问题,已经有一个。这是关于这种特定方式是否有效。)

最佳答案

一般的经验法则是 any sort of custom queries or customized query behavior should go into manager methods.
这在您的情况下是有意义的,因为您可以在非常低的级别增加、保存和返回版本号:在实际查询期间。

因此,使用管理器( object = MyManager() )并编写一个 SQL 查询来增加版本号( UPDATE mytable SET version=(version+1) WHERE pk=pk ,参见 here ),并在任何其他可以执行的调用模型实例之前立即返回增加的版本。

另见 Managers

关于python - 这是在 Django 中递增和获取计数器值的安全方法吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7148859/

10-12 15:42