одновременное обращение к базе

PAG

Новичок
одновременное обращение к базе

Задача следующая:
есть две таблички, основная и вспомогательная.
Скрипт делает выборку из первой таблицы по определенному условию и переносит данные во вторую, потом они обрабатываются. Данные забираются порциями, т.е. могут быть взяты не все, что удовлетворяют условию.
Проблема вот какая, требуется учесть случай, когда два процесса обработки запустятся одновременно, тогда во вторую таблицу данные попадут два раза.
Из этой ситуации есть несколько выходов, но нормального я не нашел.
1. Я попытался выбирать из первой таблицы только те, которых еще нет во второй и сразу их туда вставлять. Все это одним запросом, и было бы нормально, если бы insert...select работал. В описании этой команды стоит условие, что в селекте не может быть таблицы, в которую вставляются данные. поэтому этот вариант не подходит.
2. Выбрать данные из первой таблицы, и пометить выбранные строки каким-нибудь флагом, чобы дальше они не выбирались, но и этого одним запросом сделать нельзя. А если делать двумя, то в промежуток между ними может вклиниться другой процесс и все испортить.
3. Выбирать не скопом, а по одной строке, переносить данные и помечать их в первой таблице. Это некрасиво, т.к. выполняется много запросов в цикле, но зато меньше вероятность того, что между ними попадет другой процесс.


Подскажите, что можно придумать?
 

Кром

Новичок
Когда один процесс запустился, ставить идентификатор запущенного процесса. Когда процесс закончен, сбрасывать идентификатор.
 

ForJest

- свежая кровь
попытался выбирать из первой таблицы только те, которых еще нет во второй и сразу их туда вставлять. Все это одним запросом, и было бы нормально, если бы insert...select работал. В описании этой команды стоит условие, что в селекте не может быть таблицы, в которую вставляются данные. поэтому этот вариант не подходит.
Это ограничение убрали в 4.0.17 по-моему.
К тому же можно осуществить перенос через временную таблицу
Выбрать данные из первой таблицы, и пометить выбранные строки каким-нибудь флагом, чобы дальше они не выбирались, но и этого одним запросом сделать нельзя. А если делать двумя, то в промежуток между ними может вклиниться другой процесс и все испортить.
Для этого придумали LOCK TABLES - чтобы никто не мог вклинится. Т.е.
[sql]
LOCK TABLES my_table WRITE;
SELECT * FROM ...;
UPDATE my_table SET flag = 'Yes' WHERE id IN (<ids, которые мы выбрали>);
UNLOCK TABLES;
[/sql]

-~{}~ 14.06.05 19:52:

Подскажите, что можно придумать?
В целом - блокировать и помечать записи - хорошая идея.
Выбрал/пометил/перенёс.
Другим решением может быть - "один и только один процесс".
Т.е. в начале работы скрипта проверять, что он является единственной рабочей копией.
 

PAG

Новичок
Спасибо!
Я решил выбрать вариант пометки/переноса.
 
Сверху