Транзакция со многими вставками без блокировки таблицы

#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;