我有一个模型 MyModel,它有一个字段 expiration_datetime。
每次用户检索 MyModel 的实例时,我首先需要 检查它是否已过期。如果它已经过期,那么我需要 增加一些计数器,更新其他计数器,然后扩展 expiration_datetime 到 future 的某个时间。
所以 View 会做类似的事情:
if object.expiration_datetime < datetime.datetime.now():
object.counter = F('counter') + 1
object.expiration_datetime = F('expiration_datetime') + datetime.timedelta(days=1)
object.save()
上面的代码中存在竞争条件。说线程 1 检查和 发现当前实例已经过期,继续递增 计数器并延长到期日期时间。但在它做之前 因此,线程 2 被调度并执行相同的操作。到时候线程 1 终于完成了,计数器已经增加了两次并且 expration_datetime 已延长两次。
这看起来应该是一个很常见的问题。最有效的处理方法是什么?理想情况下,我希望能够以数据库可移植的方式在 Django 中处理它。
最佳答案
这可能是 optimistic locking 的一个很好的用例.有几种方法可以做到这一点:
- 您可以有一个版本号,然后运行您的
UPDATE
查询,以便它始终在WHERE
子句中包含版本号,然后检查是否有任何行改变了。 - 在
WHERE
子句中包含记录的每个值(在您所做的更改之前),这样您就可以确保您正在保存的记录与您读取它时完全相同。
如何在Django中实现乐观锁?查看此问题:Django: How can I protect against concurrent modification of data base entries .
关于python - 你如何在 Python/Django/MySQL 中避免这种竞争条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3653592/