2011-01-20 41 views
0

我有一张表,它类似于我想要访问的URL列表。该表未被引用,也未引用其他表。 什么我的应用程序做的是:如何锁定一些行,因为他们不会在其他交易中被选中

  • 从URL
  • 的列表中选择一些行开始一个周期对他们
    • 开始transacion
    • 访问URL
    • 阐述它
    • 开始一个子交易
      • 检查结果是否已经在fi前两个表(选择)
      • 如果不是,将其保存(插入)
    • 提交子事务
    • 启动子事务
      • 检查结果是否已经在另一个表(选择)
      • 如果不是,将其保存(插入)
    • 提交子事务
    • 更新我参观
    • 行提交主要交易
  • 结束周期

有大量的错误检查在这里和那里,主要交易有数百个查询(选择和插入),MySQL在CPU上非常高(我猜是因为大的回滚日志),但所有这些工作正常。

只有我不能运行这个批处理的多个实例,因为它选择的行大致相同:这意味着我在几秒钟内多次访问一个URL,这是我不想要的。

如果我将主事务的开始移动到循环之外并选择要更新的行,仍然没有获得多并发性,因为第二个实例在第一个实例的主事务获胜之前不会运行select不承诺。

一个可能的解决方案是添加一个“锁定”字段到第一个表设置为true(实际上到当前日期,因为我试图不使用布尔值)。

另一个是启动主要事务,然后一次只选择一行(更新)(设置“限制1”而不是5或10)。

我无法想像其他方式得到我想要的:不要选择锁定的行。

任何想法?

+0

*“我尽量不要使用布尔值”*。多么奇怪。出于好奇,这是有原因的吗? – LukeH 2011-01-20 16:29:45

+0

试图不使用提供给你的工具阻碍了你的发展。你看到画家拒绝滚筒吗? – 2011-01-20 17:13:18

回答

1

听起来好像您确实需要某种形式的标记来将行标识为“正在使用”,以便其他实例不处理相同的数据;不管你使用布尔类型还是日期类型都无关紧要,你必须标记正在使用的行。

您既可以通过调度程序,进程或线程访问您的表,也可以只选择行并将其传递给其他进程以进行工作。即使这样,调度员也必须知道他们得到的数据有多远才能回到同样的问题。

另一种方法是使用一个字段来指示行正在使用中(正如您在问题中所说的那样)。每个进程用一个唯一的ID更新一个行块,在一个事务中执行来锁定表;我会使用从CONNECTION_ID()返回的连接号码来标记它们,然后您知道它是唯一的。

UPDATE ... WHERE connection_id IS NULL(限制应用)事务处理完成后,进程可以SELECT ... WHERE connection_id = CONNECTION_ID()获取它们的行进行处理。

当他们完成他们的工作后,整个周期再次开始标记下一组行,直到所有行都被处理完毕。

相关问题