繁体   English   中英

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

[英]Multi-threading : Multiple threads interacting with same table

面试问题

假设我们有一个表,在Employee表中有200万条记录,我们需要削减每位员工的10%薪水(需要进行一些处理),然后将其保存回集合。 您如何有效地做到这一点。

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

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

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

请帮忙。

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

给出问题的最佳方法是使用纯SQL,例如:

update employees set
salary = salary * .9

很难想象需要对SQL无法处理的员工数据执行某些操作。

如果由于设计错误而确实需要对雇员类型的数据做一些SQL绝对无法做到的事情,那么您将打开一个游标到行集并对其进行遍历,以同步进行更新,因此您只需要对数据。

用伪代码:

cursor = forUpdate ("select for update * from employees")
while (cursor.next()) {
    cursor.salary = cursor.salary * .9
}

这是最简单且可能最快执行的方法。

---

关于日志

它只有200万行,数量很少,因此大多数DB可以在单个事务中处理它。 但是,如果没有,则在查询中添加一个where子句,例如where id between <start> and <end>以使用shell脚本方法将进程分块为可记录数量。

如果使用代码方法,大多数数据库都允许您在打开游标的同时提交,因此只需每10K行左右提交一次。

关于锁定

与日志记录类似的方面。 这种查询中的所有行在事务期间都被锁定。 鉴于要花这么长时间才能运行,请选择一个安静的时间运行。 如果这确实很重要,请整理一下,但要意识到锁是不可避免的。

我将在此表中加载,然后为状态添加一列。 默认情况下,您可以将此列设置为“未处理”。 一旦线程开始处理此员工,它将状态更改为“正在处理”,然后在完成后最终将其切换为“已处理”。

具有3个这样的状态还可以使您将其用作锁定,从而防止处理发生两次。

暂无
暂无

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

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