繁体   English   中英

数据库优化中的多线程选择行

[英]Multiple thread selecting row from database optimisation

我有一个Java应用程序,其中有15个线程通过一个名为getNext()的同步方法从具有11,000条记录的表中选择一行,这些线程在选择一行时变慢,从而花费了大量的时间。 每个线程都遵循以下过程:

  1. 线程检查是否将恢复列值设置为1的行存在。

    答:如果存在,线程将获取该行的ID,然后使用该ID选择ID大于接受ID的另一行。

    B.否则,选择ID大于0的行。

  2. 根据上面1中描述的步骤的结果收到的最后一行,将简历列设置为1。

  3. 线程获取行数据并对其进行处理。

题:

  1. 多线程如何访问同一表并选择另一个线程未选择的行并且快速?
  2. 在任何一个线程选择的最后一行发生崩溃的情况下,如何使线程恢复?

1 .:似乎getNext()中的多个数据库操作成为瓶颈。 如果外部源没有更改数据,则可以读取所有行的“ id”和“ resume”并将其缓存。 比起您只有一个查询,而不是仅在内存中进行读取操作。 这样可以安全地在getNext()中进行许多昂贵的数据库调用:

2:基本上,您需要某种事务或至少添加另一列,当线程完成处理该行时,该列将更新。 基本上,处理和更新需要在单个事务中进行。 当事务未完成时发生某些事情时,您可以回滚到未处理该行的状态。

如果所有线程都在同一台计算机上,则它们可以使用共享数据结构来避免在同一事物上工作,而不必进行同步。 但是以下内容假定线程位于不同的机器上(可能是应用程序服务器集群的不同成员),并且只能通过数据库进行通信。

删除getNext()方法上的同步。 将恢复标志设置为1(步骤2)时,请自动进行。 更新表集resume = 1,其中resume = 0,提交。 只有一个线程会成功执行此操作,执行该任务的线程将获得该工作单元。 同时,设置恢复时间-如果恢复时间大于某个最大值,则假定工作在该工作单元哈希上的线程崩溃了,请将恢复标志设置回0。工作完成后,将恢复时间设置为null ,否则将工作标记为已完成。

好吧,这里会想到不同的问题:

  1. 您是否在数据库中保持状态? 我会寻找一种方法,您将其称为“选择更新”,并根据不活动状态进行过滤(确保仅在选择中获得一行),然后立即更新为活动状态(在同一事务中)。 知道您使用的是哪个数据库将非常高兴,不确定是否始终选择“选择更新”。

  2. 处理,完成后,更新为完成状态。

  3. 确保最后一次更改状态时在表中保留一个时间戳以进行标识。 使自己成为一个规则,以决定何时将活动线程视为丢失。

  4. 定义其他可能的错误方案(如果过程失败,将会发生的情况)。

您还需要分析场景。 您的表格有几行? 有多少个线程并发调用它? 在给定的时间内发生了几次插入? 取决于此,您将必须查看数据库性能如何运行。

我假设您的getNext()已同步,并且与我在点1上写的内容一样,您可能会解决此问题...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM