Многопоточность: несколько потоков, взаимодействующих с одной и той же таблицей - PullRequest
0 голосов
/ 02 июля 2019

Вопрос для интервью

Скажем, у нас есть таблица с 2 миллионами записей в таблице Employee, и нам нужно сократить заработную плату 10% (необходимо провести некоторую обработку) каждого сотрудника, а затем сохранить ее в коллекции. Как вы можете сделать это эффективно.

Я спросил его, что мы можем использовать структуру executor для того же самого, чтобы создать несколько потоков, которые могут извлекать значения из таблицы, затем мы можем обрабатывать и сохранять их в списке.

Затем он спросил меня, как вы проверите, что запись уже обработана или нет, там я был не в курсе (как это сделать).

даже я не уверен, хорош ли я с моим подходом или нет.

пожалуйста, помогите.

Ответы [ 3 ]

1 голос
/ 02 июля 2019

Одна вещь, которую вы могли бы сделать, это использовать модель типа производитель / потребитель, где у вас есть один поток, работающий для подачи другим для обновления записей.Таким образом, вам не придется беспокоиться об обработке дубликатов.

1 голос
/ 02 июля 2019

Лучший подход к заданному вопросу - использовать чистый SQL, например:

update employees set
salary = salary * .9

Очень трудно представить, что нужно что-то делать с данными сотрудника, которые SQL не может обработать.

Если по какому-то причудливому замыслу вам действительно нужно было сделать что-то для данных типа сотрудника, чего SQL абсолютно не может сделать, то вы бы открыли курсор на наборе строк и провели итерацию по нему, производя обновление синхронно, так что вы делаете только один проход данных.

В псевдокоде:

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

Это самый простой и, вероятно, самый быстрый подход к исполнению.

-

Относительно регистрации

Это всего 2M строк, что является «небольшим» количеством, поэтому большинство БД может обрабатывать его за одну транзакцию. Однако, если нет, добавьте предложение where, например, where id between <start> and <end>, к запросу, чтобы разделить процесс на регистрируемые суммы при использовании подхода сценария оболочки.

Если используется кодовый подход, большинство баз данных позволяют вам фиксировать, удерживая курсор открытым, поэтому просто фиксируйте каждые 10K строк или около того.

Относительно блокировки

Подобные аспекты ведения журнала. Все строки в таком запросе блокируются на время транзакции. Учитывая, что это займет так много времени, выбери тихое время для бега. Если это действительно важно, разберитесь, но поймите, что блокировка неизбежна.

0 голосов
/ 02 июля 2019

Я бы загрузил в эту таблицу, а затем добавить столбец для состояния. По умолчанию вы можете установить для этого столбца значение «Не обработано». Как только поток начинает обрабатывать этого сотрудника, он меняет состояние на «Обработка», затем, когда он завершает работу, он, наконец, переключается на «Обработано».

Наличие 3 таких состояний также позволит вам использовать это в качестве блокировки, предотвращая повторную обработку дважды.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...