Я помогал некоторым моим коллегам с проблемой SQL. В основном они хотели переместить все строки из таблицы A в таблицу B (обе таблицы имеют одинаковые столбцы (имена и типы)). Хотя это было сделано в Oracle 11g, я не думаю, что это действительно имеет значение.
Их первоначальная наивная реализация была похожа на
BEGIN
INSERT INTO B SELECT * FROM A
DELETE FROM A
COMMIT;
END
Их беспокоило, были ли INSERT, сделанные в таблицу A во время копирования из A в B, и «DELETE FROM A» (или TRUNCATE для того, что стоило) вызвало бы потерю данных (удаление новых вставленных строк в A).
Конечно, я быстро порекомендовал сохранить идентификаторы скопированных строк во временной таблице, а затем удалить только те строки в A, которые соответствуют IDS во временной таблице.
Однако для любопытства мы поставили небольшой тест, добавив команду ожидания (не помню синтаксис PL / SQL) между INSERT и DELETE. Затем из другого соединения мы вставили бы строки ВО ВРЕМЯ ОЖИДАНИЯ .
Мы заметили, что это потеря данных. Я воспроизвел весь контекст в SQL Server и обернул все это в транзакцию, но все же свежие новые данные также были потеряны в SQL Server. Это заставило меня думать, что в первоначальном подходе есть систематическая ошибка / недостаток.
Однако я не могу сказать, был ли это тот факт, что TRANSACTION не был (каким-то образом?) Изолирован от новых новых INSERT или тот факт, что INSERT пришли во время команды WAIT.
В конце концов, это было реализовано с использованием предложенной мной временной таблицы, но мы не смогли получить ответ на вопрос «Почему потеря данных». Ты знаешь почему?