【问题标题】:Implement SELECT ... FOR UPDATE NOWAIT (sort of) for mysql 5.7 in python?在python中为mysql 5.7实现SELECT ... FOR UPDATE NOWAIT(某种)?
【发布时间】:2021-05-31 08:37:00
【问题描述】:

我需要实现一种方法来允许并发读取来检查记录是否已设置。如果设置它们只是返回。如果不是,则第一个读取进程/线程将根据它获得的结果对其进行设置。这样做的目的是只运行一次初始化脚本

如果我使用mysql 8.0,我想我可以使用SELECT ... FOR UPDATE NOWAIT,所以如果一个进程/线程未能获得锁,这意味着另一个进程/线程已经获得它,所以它可以返回。获得锁的人将决定是否需要运行初始化脚本并更新记录。

但是我用的是mysql 5.7,没有NOWAIT,如果我用SELECT ... FOR UPDATE,并发读取就变成一一等待锁了。我觉得还不够好。那么是否可以实现一个自制的NOWAIT(在python中)?

我的目标是确保初始化脚本只运行一次,所以如果没有NOWAIT,还有其他方法吗?

【问题讨论】:

    标签: python mysql multithreading concurrency locking


    【解决方案1】:

    我在https://softwareengineering.stackexchange.com/questions/426902/how-do-i-make-sure-a-task-run-only-once-in-a-dockerized-environment 提出的类似问题得到了答案

    我总结了我学到的关于如何实施nowait 的知识,所有的功劳都归于那里的答案,尤其是菲尔的答案。

    UPDATE your_table
    SET running_update = 1
    WHERE running_update = 0
    

    然后检查更新的行数 - UPDATE 语句的第一次运行实际上会更新该行,所以得到 1。那是继续运行任务的那个。

    虽然所有后续运行都不会进行任何更改并得到 0,因此它们可以返回。

    所以基本上这与使用setnx in redis 锁定相同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-10
      • 1970-01-01
      • 1970-01-01
      • 2011-05-17
      • 2012-11-21
      相关资源
      最近更新 更多