serovvitaly
@serovvitaly

Параллельная транзакция mysql?

Имеются несколько конкурентных процессов, работающих с одной таблицей mysql. Каждый процесс делает выборку из таблицы 100 записей и обрабатывает их.
SELECT * FROM table LIMIT 100 FOR UPDATE;
Если запустить транзакцию, то каждый процесс будет ждать завершения транзакции предыдущего процесса, а нужно, что бы выбирались только незаблокированные строки без ожидания окончания конкурентной транзакции.

Задача довольно избитая и уже не раз обсуждалась в сети, но результата пока нет. SELECT ... FOR UPDATE не помогает.

Пометка предварительно нужных записей уникальным PID - не подходит, т.к. таблица большая и нагрузка дополнительными UPDATE ... SET pid=*** - совсем не уместна.
  • Вопрос задан
  • 4610 просмотров
Пригласить эксперта
Ответы на вопрос 4
@Confl1kt
используйте очередь(redis, rabbitMQ)
загружаете все ид записей, которые необходимо обработать, в очередь
куча процессов достаёт из очереди по одной записи, пока они не закончатся, и обрабатывают
Ответ написан
egor_nullptr
@egor_nullptr
Заводим вспомогательную таблицу с одной единственной записью, обозначающей максимальный ID обрабатываемых записей.
CREATE TABLE limit_id_table (
    max_id int unsigned not null
) ENGINE=innodb;

INSERT INTO limit_id_table values (0);

Перед запуском транзакции проводим UPDATE этой записи с возвратом обновленного значения, по этому значению определяем интервал ID для обработки.
UPDATE limit_id_table set max_id = @max_id := max_id + 100;
BEGIN;
SELECT * FROM table where id BETWEEN @max_id - 99 AND @max_id FOR UPDATE;
.....
COMMIT;
Ответ написан
Если разбить на более мелкие транзакции и проводить их по очереди?
Ответ написан
stavinsky
@stavinsky
Если актуальность данных не сильно важна, возможно начать с уровня изоляции транзакций?
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы