python - 你如何在 Python/Django/MySQL 中避免这种竞争条件?

标签 python mysql database django race-condition

我有一个模型 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/

相关文章:

database - 刷新 MQT 时如何避免在 DB2 中遇到事务日志空间问题?

python - 无法使用 !pip install textract 安装 textract

python - Plotly:如何在绘图中添加垂直线?

php - 防止将链接添加到另一个链接

mysql - 在 MySQL 中使用 Group By 将两个查询合并为一个

c++ - 使用来自远程计算机的 libpq 在 PostgreSQL 中插入二进制大对象 (BLOB)

聚合查询的 MongoDB 执行时间

python - 用 Nose 重复单次或多次测试

python - 计时和重定向子进程 :PIPE output to file

mysql - 如何在 MySQL 中为每个类别选择 3 行?