【问题标题】:Concurrent access problem in mysql databasemysql数据库并发访问问题
【发布时间】:2010-02-23 20:19:31
【问题描述】:

您好,我正在编写一个 python 脚本,该脚本将创建一些从数据库中获取和执行任务的子进程。

任务由在同一台机器上运行的 php 网站插入到数据库中。

有什么好的方法(需要快速)来选择和更新那些“正在进行”的任务以避免被 python 脚本多次选择

编辑:数据库是 mysql

提前致谢

【问题讨论】:

  • 您使用的是哪个数据库? SQL Server,MySQL?
  • 对不起,我忘了在问题中指定。这是 MySQL

标签: sql mysql database concurrency


【解决方案1】:

使用 InnoDB 表 Tasks,然后:

select TaskId, ... from Tasks where State="New" limit 1;
update Tasks set State="In Progress" where TaskId=<from above> and State="New";

如果更新成功,您可以继续执行任务。否则,请重试。

您需要一个关于 TaskId 和 State 的索引。

【讨论】:

  • 太好了,这样我可以同时进行插入吗?也许我可以将此代码改编成存储过程?
  • 您可以同时插入新的任务行,是的。我敢打赌,你可以让我的代码成为一个存储过程,这样你只需要一次往返数据库(我的代码需要 2+)。
  • 我想知道锁定/选择/更新/解锁和使用多个键选择/更新之间的权衡是什么。
  • 只是想我会注意到你可以像这样使这个更新原子化:update Tasks set TaskId=(@working_taskid:=TaskId), State="In Progress" where State="New" limit 1; select @working_taskid;。如果您对任务有很多争用,这可能会提供更好的性能。
【解决方案2】:

在不了解您的架构的情况下,我建议使用以下方法。

1) Lock Process table
2) Select ... from Process table where State="New"
3) processlist = [list of process id''s from step 2]
4) Update Process table set State="In progress" where ProcessId in [processlist]
5) Unlock Process table.

【讨论】:

  • 过程与此非常相似,但每个 python 脚本一次获取 1 个任务。我想锁定桌子,但它正在寻找一种更快的方法。
  • 将 LIMIT 1 放入您的选择中(第 2 步)我看不到绕过锁的方法。
【解决方案3】:

加快处理速度的一种方法是将过程放入存储过程中,并从该过程中返回选定的行。这样一来,db server 只需要一趟。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-17
    • 1970-01-01
    相关资源
    最近更新 更多