我正在开发一个应用程序,其中包含了一些数据。现在,我想根据列“RefreshMe”刷新该表中的一些行。
例如:
CREATE TABLE IF NOT EXISTS `datatable` (
`id` bigint(20) NOT NULL,
`row_created` datetime(6) NOT NULL,
`row_modified` datetime(6) DEFAULT NULL,
`refresh_me` bit(1) DEFAULT NULL,
`refresh_date` datetime(6) DEFAULT NULL,
`next_refresh_date` datetime(6) DEFAULT NULL,
`refresh_days` int(11) NOT NULL,
`version` bigint(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
如果RefreshMe为true,则应刷新该行。
问题是:如何从多线程应用程序中选择该表中的行,同时尽量减少冲突?
我不想使用select for update
来完成这个任务。只需使用乐观锁(springjpa)。
如果我只使用select * from datatable where refresh_me = 1 order by row_modified asc;
,那么线程将获得相同的行,并且应该解析乐观锁。
我能想到的唯一方法是选择100行,随机选取10行并使用它们。这将减少2-10个正在运行的线程之间的冲突。
如何解决100个线程的任务?”””有更好的方法来做到这一点?**
1条答案
按热度按时间qyyhg6bp1#
“多线程”是指刷新行的大量进程?
如果是这样的话,我建议你使用预先预订。
将
refresh_me
更改为BIGINT UNSIGNED NULL。接受以下值:
当必须刷新行时,则将其
refresh_me
设置为0。必须刷新行的线程保留所需的行数,以便用
如果受影响的行的数量为零,则不存在需要刷新的行,并且线程可以退出或休眠。
然后,它使用以下命令逐个处理保留行(由于并发线程干扰,它们的数量可能小于指定的NNN值):
迭代保留行,直到下一次迭代不返回保留行(即,即所有保留行都已被处理)。在这种情况下,下一行块被保留。
使用这种预保留,保留大量行是没有意义的。您只能保留一行(i)。即使用LIMIT 1),然后处理它,或者如果行被并发线程重新保留(在UPDATE LIMIT 1之后进一步SELECT不返回行),重复保留该行的尝试。
线程可能挂起/失败。因此,我建议您添加自动使用的
updated_at
列,并创建一个事件过程,该过程检查保留但从保留时间点经过的时间太高的行,并将这些行返回到需要用简单刷新的行池。