У меня есть пакеты SSIS, которые оба вызывают пакет с именем Refresh Exchange Rates
, прежде чем они загрузятся, потому что эти другие пакеты зависят от обновляемых обменных курсов.Выполнение одного и того же кода несколько раз вызывает ошибку ограничения первичного ключа
В таблице Exchange Rate есть ограничения первичного ключа для предотвращения дублирования записей. Иногда пакет Refresh Exchange Rates
запускается несколько раз одновременно, так как несколько пакетов вызывают один и тот же код. Ниже приведен код, который работает, однако он производит ограничение первичного ключа, когда запускать несколько раз:
TRUNCATE TABLE dbo.FactExchangeRate
INSERT INTO dbo.FactExchangeRate (
FromCurrencyId,
ToCurrencyId,
RateDate,
ExchangeRate
)
SELECT
FromDimCurrency.Id AS FromCurrencyId,
ToDimCurrency.Id AS ToCurrencyId,
CAST(AXCURD.DT AS DATE) AS RateDate,
AXCURD.EXRATE AS ExchangeRate
FROM
DataWarehouseRawData.dbo.AXCURD
INNER JOIN
dbo.DimCurrency FromDimCurrency ON
FromDimCurrency.SourceKey = AXCURD.FRAXCURIDX
INNER JOIN
dbo.DimCurrency ToDimCurrency ON
ToDimCurrency.SourceKey = AXCURD.TOAXCURIDX
Что я могу сделать, чтобы предотвратить это? Я знаю, что код работает несколько раз (3 раза в этом случае), поэтому я предполагаю, что это как-то связано с транзакциями и т. Д.
Я попытался использовать TABLOCKX
на вставке, измените TRUNCATE
до DELETE
(для транзакций), а также попробовал BEGIN TRANSACTION
и т. Д., Но это в конечном итоге вызвало тупик.
Вместо шаблона TRUNCATE/ВСТАВИТЬ использовать INSERT/UPDATE/DELETE шаблон или команду MERGE. В общем, это лучшая идея, чем усечение/вставка, особенно в хранилище данных. Например, прямо сейчас вы, вероятно, не можете создавать внешние ключи в хранилище данных, потому что они не смогут выполнить процесс загрузки. Если вам нужна дополнительная информация, дайте мне знать –
Большинство наших измерений объединены, но это один из наших фактов, который мы усекаем и перезагружаем, так как это быстрый процесс. У нас специально нет внешних ключей. Можете ли вы объяснить, почему слияние поможет моей проблеме? Разве это не просто слияние синтаксического сахара для операции dml? – Lock
Слияние не будет вставлять запись, которая уже существует .. теоретически, но поскольку у вас много сеансов, я не уверен. Лично я предпочитаю отдельные инструкции INSERT/UPDATE/DELETE для MERGE, потому что, видимо, у него есть некоторые ошибки (которые теперь могут быть исправлены). Более «фундаментальным» решением было бы включить изоляцию моментальных снимков, а затем использовать транзакции, а это означает, что когда ваша таблица заблокирована внутри транзакции, все остальное использует версию ранее существовавшей таблицы, не будучи заблокированной. –