[英]Multiple thread selecting row from database optimisation
我有一个Java应用程序,其中有15个线程通过一个名为getNext()的同步方法从具有11,000条记录的表中选择一行,这些线程在选择一行时变慢,从而花费了大量的时间。 每个线程都遵循以下过程:
线程检查是否将恢复列值设置为1的行存在。
答:如果存在,线程将获取该行的ID,然后使用该ID选择ID大于接受ID的另一行。
B.否则,选择ID大于0的行。
根据上面1中描述的步骤的结果收到的最后一行,将简历列设置为1。
线程获取行数据并对其进行处理。
题:
1 .:似乎getNext()中的多个数据库操作成为瓶颈。 如果外部源没有更改数据,则可以读取所有行的“ id”和“ resume”并将其缓存。 比起您只有一个查询,而不是仅在内存中进行读取操作。 这样可以安全地在getNext()中进行许多昂贵的数据库调用:
2:基本上,您需要某种事务或至少添加另一列,当线程完成处理该行时,该列将更新。 基本上,处理和更新需要在单个事务中进行。 当事务未完成时发生某些事情时,您可以回滚到未处理该行的状态。
如果所有线程都在同一台计算机上,则它们可以使用共享数据结构来避免在同一事物上工作,而不必进行同步。 但是以下内容假定线程位于不同的机器上(可能是应用程序服务器集群的不同成员),并且只能通过数据库进行通信。
删除getNext()方法上的同步。 将恢复标志设置为1(步骤2)时,请自动进行。 更新表集resume = 1,其中resume = 0,提交。 只有一个线程会成功执行此操作,执行该任务的线程将获得该工作单元。 同时,设置恢复时间-如果恢复时间大于某个最大值,则假定工作在该工作单元哈希上的线程崩溃了,请将恢复标志设置回0。工作完成后,将恢复时间设置为null ,否则将工作标记为已完成。
好吧,这里会想到不同的问题:
您是否在数据库中保持状态? 我会寻找一种方法,您将其称为“选择更新”,并根据不活动状态进行过滤(确保仅在选择中获得一行),然后立即更新为活动状态(在同一事务中)。 知道您使用的是哪个数据库将非常高兴,不确定是否始终选择“选择更新”。
处理,完成后,更新为完成状态。
确保最后一次更改状态时在表中保留一个时间戳以进行标识。 使自己成为一个规则,以决定何时将活动线程视为丢失。
定义其他可能的错误方案(如果过程失败,将会发生的情况)。
您还需要分析场景。 您的表格有几行? 有多少个线程并发调用它? 在给定的时间内发生了几次插入? 取决于此,您将必须查看数据库性能如何运行。
我假设您的getNext()已同步,并且与我在点1上写的内容一样,您可能会解决此问题...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.