2016-06-21 3 views
0

У меня есть пакеты 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 и т. Д., Но это в конечном итоге вызвало тупик.

+0

Вместо шаблона TRUNCATE/ВСТАВИТЬ использовать INSERT/UPDATE/DELETE шаблон или команду MERGE. В общем, это лучшая идея, чем усечение/вставка, особенно в хранилище данных. Например, прямо сейчас вы, вероятно, не можете создавать внешние ключи в хранилище данных, потому что они не смогут выполнить процесс загрузки. Если вам нужна дополнительная информация, дайте мне знать –

+0

Большинство наших измерений объединены, но это один из наших фактов, который мы усекаем и перезагружаем, так как это быстрый процесс. У нас специально нет внешних ключей. Можете ли вы объяснить, почему слияние поможет моей проблеме? Разве это не просто слияние синтаксического сахара для операции dml? – Lock

+0

Слияние не будет вставлять запись, которая уже существует .. теоретически, но поскольку у вас много сеансов, я не уверен. Лично я предпочитаю отдельные инструкции INSERT/UPDATE/DELETE для MERGE, потому что, видимо, у него есть некоторые ошибки (которые теперь могут быть исправлены). Более «фундаментальным» решением было бы включить изоляцию моментальных снимков, а затем использовать транзакции, а это означает, что когда ваша таблица заблокирована внутри транзакции, все остальное использует версию ранее существовавшей таблицы, не будучи заблокированной. –

ответ

0

Похоже, вам просто нужно сэкономить время, чтобы пакеты не работали друг над другом. Являются ли эти пакеты настроены под одной задачей сервера sql или есть несколько заданий? Если последний, попробуйте планировать задания на расстоянии 5-10 минут, чтобы дать каждому заданию время для завершения. И если все ваши пакеты находятся под одним заданием, разделите пакеты на отдельные этапы работы и убедитесь, что шаги выполняются в последовательном порядке.

+0

Это не решение проблемы! Вы можете сказать, что запустите его один раз в неделю в воскресенье утром, когда никто не входит в систему ... – BIDeveloper

+1

@ BIDeveloper: Ответ Стоунша может быть решением. Некоторое время назад у нас был тот же случай. Наш SQL-сервер постоянно работал в блокировках ресурсов. Причина в том, что все работы начались одновременно. btw: Не высмеивайте других только потому, что у вас никогда не было проблемы и, следовательно, не удалось соединить точки. Ты просто высмеиваешь себя – Johannes

Смежные вопросы