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

Mik*_*ler 14 sql database concurrency sybase multithreading

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

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

我应该从哪里开始?

Mar*_*rkR 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是为了避免查询不确定.


Vin*_*ent 5

虽然我理解意图,但我不同意立即进行行级锁定。这将减少您的响应时间,实际上可能会使您的情况变得更糟。如果在测试后您发现 APL 存在并发问题,您应该首先迭代移动到“数据页”锁定!

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

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

测试您的方法而不先在 APL 上移动(所有页面锁定“默认”),然后如果发现问题移动到 DOL(先是数据页,然后是数据行)。请记住,当您将表切换到 DOL 时,该表上的所有响应都会变得稍差,该表使用更多空间并且该表变得更容易产生碎片,这需要定期维护。

所以简而言之,不要直接转向数据行,先尝试并发方法,然后如果出现问题,首先使用数据页锁定,然后再使用最后的数据行。