mysql - 如何锁定对 MySQL 表的读/写,以便我可以选择然后插入,而无需其他程序读/写数据库?

标签 mysql locking web-crawler mysql-error-1093

我正在并行运行多个网络爬虫实例。

每个爬虫从表中选择一个域,将该 url 和开始时间插入到日志表中,然后开始对该域进行爬取。

其他并行爬虫在选择自己的要爬取的域之前检查日志表以查看哪些域已经被爬取。

我需要阻止其他爬虫选择一个刚刚被另一个爬虫选择但还没有日志条目的域。我对如何做到这一点的最佳猜测是在一个爬虫选择一个域并在日志表中插入一行(两个查询)时锁定数据库以防止所有其他读/写操作。

这到底是怎么做到的?恐怕这非常复杂,并且依赖于许多其他事情。请帮助我开始。


这段代码似乎是一个很好的解决方案(但是请参阅下面的错误):

INSERT INTO crawlLog (companyId, timeStartCrawling)
VALUES
(
    (
        SELECT companies.id FROM companies
        LEFT OUTER JOIN crawlLog
        ON companies.id = crawlLog.companyId
        WHERE crawlLog.companyId IS NULL
        LIMIT 1
    ),
    now()
)

但我不断收到以下 mysql 错误:

You can't specify target table 'crawlLog' for update in FROM clause

有没有办法在没有这个问题的情况下完成同样的事情?我尝试了几种不同的方法。包括这个:

INSERT INTO crawlLog (companyId, timeStartCrawling)
VALUES
(
    (
        SELECT id
        FROM companies
        WHERE id NOT IN (SELECT companyId FROM crawlLog) LIMIT 1
    ),
    now()
)

最佳答案

您可以像这样使用 MySQL LOCK TABLES 命令锁定表:

LOCK TABLES tablename WRITE;

# Do other queries here

UNLOCK TABLES;

见:

http://dev.mysql.com/doc/refman/5.5/en/lock-tables.html

关于mysql - 如何锁定对 MySQL 表的读/写,以便我可以选择然后插入,而无需其他程序读/写数据库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6621303/

相关文章:

mysql - 导轨 : Trouble with has many through relationships

postgresql - PostgreSQL 中的 ROW EXCLUSIVE 到底是什么?

java - 锁拆分与锁 strip 化

input - 在Scrapy中获取输入值

upgrade - 将 mysql (5.5) 生产数据库升级到 5.6 并最大程度减少停机时间的最佳方法是什么

C#,DataGridView - 选择新行后包含垃圾

javascript - 如何使用ajax调用从数据库中删除表行

node.js - 为什么 fs.createReadStream ... pipe(res) 锁定读取的文件?

ruby-on-rails - ActionView::MissingTemplate:缺少模板主页/索引 - Google 抓取工具

java - 使 GWT 可爬行