猿问

多线程:多个线程与同一个表交互

面试题

比如说,我们有一张 Employee 表中有 200 万条记录的表,我们需要削减每个员工 10% 的工资(需要做一些处理),然后将其存回集合。你怎么能有效地做到这一点。

我问他我们可以使用执行器框架来创建多个线程,这些线程可以从表中获取值,然后我们可以处理并将其保存到列表中。

然后他问我你将如何检查记录是否已被处理,我对此一无所知(怎么做)。

即使我不确定我是否擅长我的方法。

请帮忙。


摇曳的蔷薇
浏览 240回答 3
3回答

饮歌长啸

给出问题的最佳方法是使用纯 SQL,例如:update employees setsalary = salary * .9很难想象需要对 SQL 无法处理的员工数据执行某些操作。如果由于某种不良设计的怪癖,您确实需要对 SQL 绝对无法执行的员工类型数据执行某些操作,那么您将打开一个指向行集的游标并遍历它,同步进行更新,这样您只需执行一次传递数据。在伪代码中:cursor = forUpdate ("select for update * from employees")while (cursor.next()) {&nbsp; &nbsp; cursor.salary = cursor.salary * .9}这是最简单且执行速度可能最快的方法。—-关于日志记录它只有 2M 行,这是一个“小”数量,因此大多数 DB 可以在单个事务中处理它。但是,如果没有,请添加一个 where 子句,例如,where id between <start> and <end>如果使用 shell 脚本方法,则将过程分块到可记录的数量的查询中。如果使用代码方法,大多数数据库允许您在保持游标打开的情况下提交,因此只需每 10K 行左右提交一次。关于锁定与日志记录类似的方面。在事务期间,此类查询中的所有行都被锁定。鉴于跑步需要那么长时间,请选择一个安静的时间跑步。如果这真的很重要,请分块,但要意识到锁定是不可避免的。

天涯尽头无女友

您可以做的一件事是使用生产者/消费者类型模型,其中您有一个线程工作以向其他线程提供要更新的记录。这样您就不必担心重复处理。

FFIVE

我会加载到这个表中,然后为状态添加一列。默认情况下,您可以将此列设置为“未处理”。一旦线程开始处理该员工,它会将状态更改为“正在处理”,然后在完成后最终将状态切换为“已处理”。拥有 3 个这样的状态还可以让您将其用作锁,防止处理发生两次。
随时随地看视频慕课网APP

相关分类

Java
我要回答