Во-первых, ответ на ваш начальный вопрос; как заставить передачу данных все или ничего.
Это на самом деле довольно просто, так как вы используете хранимую процедуру для передачи данных. Вы можете заключить весь процесс передачи данных в явную транзакцию. Таким образом, если что-то идет на юг в середине процесса, ВСЕ откатывается.
Итак, с небольшим псевдокодом:
BEGIN TRY
BEGIN TRANSACTION
INSERT Table1 ...
SELECT ...
FROM ...
INSERT Table2 ...
SELECT ...
FROM ...
...
INSERT TableN ...
SELECT ...
FROM ...
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
--Other fancy error handling --
END CATCH;
Недостатком этого, и это может быть прерыватель сделки, является то, что он будет удерживать блокировку таблицы на всех столах, пока не будет выполнен весь перевод.
Что поднимает второй пункт. Переключение раздела.
Для флеша и заполнения, как это, это может быть отличным решением. ALTER TABLE...SWTCH
обычно выполняется в миллисекундах. Вы все еще можете заключить операторы SWITCH
в явную транзакцию, но, поскольку все происходит намного быстрее, блокировки не будут длиться почти так же долго.
BEGIN TRY
BEGIN TRANSACTION
ALTER TABLE staging.Table1 SWITCH PARTITION 1 TO live.Table1 ...
ALTER TABLE staging.Table2 SWITCH PARTITION 1 TO live.Table2 ...
...
ALTER TABLE staging.TableN SWITCH PARTITION 1 TO live.TableN ...
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
--Other fancy error handling --
END CATCH;
Кендра Литтл написала потрясающий пост в блоге, в котором много, гораздо больше подробностей о том, как сделать это неинвазивным, насколько это возможно, в вашей среде.
Почему вы должны переключать промежуточные таблицы вместо их переименования