Сведения о вопросе

Solllo

06:37, 26th August, 2020

MySQL — Синхронизация нескольких потоков

Просмотров: 360   Ответов: 6

Имеется задача: вставить N элементов в таблицу, но перед этим удостовериться, не добавлены ли уже такие элементы.

Т.е. сначала делаем что-то вроде:

SELECT COUNT(*) FROM xxx WHERE x IN (x1,x2,x3,x4,x5,x6…… x1000);

Если результат равен 0, то значит можно делать такой же массовый INSERT.

Но есть проблема — как сделать это секурно при многопоточности?

Т.е., допустим, как избежать ситуации, когда одновременно получаются 2 потока и порядок действий получается таким:

П1: SELECT COUNT(*) — получает «0»
П2: SELECT COUNT(*) — получает «0»
П1: делает INSERT
П2: т.к. получил «ноль» в предыдущем селекте, тоже делает INSERT дублирующих записей

Есть ли решение для такой задачи?

Идея выставлять какой-то глобальный флаг кажется очень кривой и глупой.

Хранимки не предлагайте, т.к. опять-таки — они не спасут от одновременности. Как вообще такие вещи делаются?

Вставлять предполагается порой большие массивы данных по несколько десятков тысяч, так что вероятно, что запросы будут выполняться не слишком быстро и есть вероятность словить баг с одновременной вставкой.



  Сведения об ответе

KOMP

18:13, 24th August, 2020

Транзакции, innodb.


  Сведения об ответе

baggs

05:00, 27th August, 2020

если x уникальное поле — то добавить UNIQUE KEY. и уточните какой у вас тип таблицы — myisam, innodb?


  Сведения об ответе

KOMP

15:51, 20th August, 2020

Простой вариант — LOCK TABLES, но лучше локами не злоупотреблять.


  Сведения об ответе

VERSUION

12:27, 3rd August, 2020

LOCK TABLES ххх WRITE;
SELECT COUNT(*) FROM xxx WHERE x IN (x1,x2,x3,x4,x5,x6…… x1000);

INSERT INTO xxx ...;
UNLOCK TABLES;

Заблокирует таблицу для других сессий. Если в запросах между блокировкой и разблокировкой будут использоваться на чтение другие таблицы например WHERE x IN (SELECT * FROM xxx1), то их тоже надо, если не ошибаюсь блокировать: LOCK TABLES ххх WRITE, xxx1 READ


  Сведения об ответе

darknet

10:13, 11th August, 2020

UNIQUE INDEX по полю и делайте INSERT IGNORE. Совпадающие поля отвалятся автоматом, такой вариант будет работать достаточно быстро.


  Сведения об ответе

ASER

18:54, 2nd August, 2020

INSERT ON DUPLICATE UPDATE и другие тригеры на вставку.
также — LOCK таблиц. Также лок мозгов на сервере и другие мьютексы.
Вариант 3 — работа через промежуточную инстацию


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться