#mysql #transactions #locking
#mysql #транзакции #блокировка
Вопрос:
У меня есть скрипт, который создает те же данные в базе данных. Похоже:
START TRANSACTION;
INSERT INTO table (data);
INSERT INTO table (data);
INSERT INTO table (data);
...
COMMIT;
Скрипт выполняется около 30 минут. Но когда это работает, таблица блокируется для других вставок. Я не могу вставить какую-либо строку из другого процесса, пока сценарий не завершится. Это необходимо? Я хотел бы использовать транзакцию, но я не могу заблокировать всю таблицу. Есть ли какой-нибудь способ сделать это?
Ответ №1:
Можете ли вы вместо этого сделать:
START TRANSACTION;
INSERT INTO table (data);
COMMIT;
START TRANSACTION;
INSERT INTO table (data);
COMMIT;
...
START TRANSACTION;
INSERT INTO table (data);
COMMIT;
Не самый элегантный, но он должен решить вашу проблему, основываясь на ситуации, которую вы описываете.
Если вам нужно, чтобы весь элемент был одной ТРАНЗАКЦИЕЙ, то лучший способ сделать это будет следующим:
INSERT INTO tmpTableA (dataX);
INSERT INTO tmpTableB (dataY);
INSERT INTO tmpTableC (dataZ);
...
' Do all the "building / processing above using temp tables either in memory or on disc, and then only when all the "heavy lifting" is done; update/insert the data into your tables.
...
START TRANSACTION;
INSERT INTO tableA (tmpTableA);
UPDATE tableB.foo = tmpTableB.fee WHERE BlahBlobBlah;
INSERT INTO tableC (tmpTableC);
COMMIT;
Вы хотите отложить запуск ТРАНЗАКЦИИ до тех пор, пока не будет выполнена вся обработка.
Комментарии:
1. Я не уверен, что это то, что мне нужно. Я хотел бы иметь транзакцию для всего процесса скрипта. Мне нужно быть уверенным, что скрипт вставил каждую строку или ничего не вставил.
2. Обновленный ответ в ответ на ваш комментарий, @Adam.
Ответ №2:
Вы должны создать временную таблицу: table_temp вставьте все данные в table_temp, когда вы будете готовы, вы можете вставить все временные данные в итоговую таблицу:
START TRANSACTION;
INSERT INTO table_temp (data);
INSERT INTO table_temp (data);
INSERT INTO table_temp (data);
insert into table
select * from table_temp;
commit;