多线程处理数据库记录的最佳实践

时间:2009-02-18 20:50:28

标签: sql database multithreading concurrency sybase

我有一个进程可以在表中查询PROCESS_IND ='N'的记录,进行一些处理,然后将PROCESS_IND更新为'Y'。

我想允许运行此进程的多个实例,但不知道避免并发问题的最佳实践是什么。

我应该从哪里开始?

5 个答案:

答案 0 :(得分:10)

我使用的模式如下:

  • 创建“lockedby”和“locktime”列,分别是线程/进程/计算机ID和时间戳(当您在多台计算机之间拆分处理时,您将需要计算机ID)
  • 每项任务都会执行以下查询:

    UPDATE taskstable SET lockedby =(我的id),locktime = now()WHERE lockedby IS NULL ORDER BY ID LIMIT 10

其中10是“批量大小”。

  • 然后每个任务执行SELECT以找出它被“锁定”以进行处理的行,并处理这些行
  • 每行完成后,将lockedby和locktime设置为NULL
  • 所有这些都是在循环中完成的,与现有的批次一样。
  • cron作业或计划任务会定期重置锁定时间过长的任何行的“lockedby”,因为它们可能是由挂起或崩溃的任务完成的。然后其他人会接他们

LIMIT 10是MySQL特定的,但我认为其他数据库具有等价物。导入ORDER BY是为了避免查询不确定。

答案 1 :(得分:4)

虽然我明白了我不同意立即进行行级别锁定的意图。这会缩短您的响应时间,实际上可能会使您的情况变得更糟。如果在测试之后您看到APL的并发问题,您应该首先迭代移动到“datapage”锁定!

要真正回答这个问题,需要更多关于表格结构和所涉索引的信息,但需要进一步解释。

DOL,数据行锁定比全页/页面级锁定使用更多的锁。管理所有锁的开销以及由于缓存中更多锁结构的请求而导致的可用内存减少将降低性能,并通过转向更加并发的方法来抵消任何增益。

测试您的方法而不首先在APL上移动(所有页面锁定'默认')然后如果看到问题移动到DOL(数据页首先然后是数据行)。请记住,当您将表格切换到DOL时,该表格上的所有响应都会变得更糟,表格会占用更多空间,而且表格更容易碎片化,需要定期维护。

所以总之不要直接转到datarows尝试你的并发方法然后如果有问题首先使用datapage锁定然后使用最后的数据行。

答案 2 :(得分:2)

您应该在表格中启用row level locking

CREATE TABLE mytable (...) LOCK DATAROWS

然后你:

  • 开始交易
  • 选择包含FOR UPDATE选项的行(将锁定它)
  • 做你想做的事。

在交易结束之前,没有其他进程可以对此行执行任何操作。

P上。 S. 有人提到使用LOCK DATAROWS可能导致的开销问题。

是的,有开销,但我很难称这是一个像这样的桌子的问题。

但是如果切换到DATAPAGES,那么每个PAGE(默认情况下为2k)只能锁定一行,并且其行位于一个页面中的进程将无法运行同时进行。

如果我们谈论的桌子会同时锁定十几行,那么几乎不会出现明显的性能下降。

流程并发对于这样的设计来说更为重要。

答案 3 :(得分:1)

最明显的方法是锁定,如果您的数据库没有锁,您可以通过添加“锁定”字段来自己实现。

简化并发性的一些方法是随机化对未处理项的访问,因此它们不是在第一项上竞争,而是随机分配访问权。

答案 4 :(得分:0)

将过程转换为单个SQL语句,并将多个行作为单个批处理。这就是数据库的工作方式。

相关问题