Как разработчик SQL Server Integration Services (SSIS) вы, возможно, сталкивались с ситуациями, когда вам нужно передавать значения между родительскими и дочерними пакетами. В то время как передача значений от дочерних пакетов к родительским легко осуществляется с помощью SSIS конфигураций, обратный процесс требует некоторого скриптинга. В этом блоге мы рассмотрим сценарий, в котором передача значений от дочерних пакетов к родителям вызывает неожиданное поведение.
Давайте рассмотрим сценарий, в котором у нас есть ETL-фреймворк, состоящий из трех уровней пакетов: прадедушка, ребенок и внук пакеты. Пакеты на уровне листьев должны иметь возможность работать как в рамках ETL-фреймворка, так и независимо. Для достижения этого мы пытаемся передать значения от родителей к дочерним пакетам и наоборот.
В недавнем проекте я столкнулся с проблемой при тестировании пошагового выполнения пакетов на уровне листьев. Проблема возникла при выполнении скриптовой задачи, которая пыталась записать значение в переменную SSIS с именем “LeafLevelConfigSetting”. Ожидалось, что эта переменная будет унаследована от родительского пакета. Задача скрипта была заключена в блок try/catch для обработки любых исключений, возникающих при вызове метода LockOneForWrite(), который должен был позволить выполнению пакета продолжиться без ошибок.
Однако, при выполнении пакета независимо, скриптовая задача каждый раз завершалась с ошибкой, сообщая, что переменная “LeafLevelConfigSetting” не может быть найдена. Это поведение было неожиданным, так как исключение должно было быть перехвачено блоком try/catch.
Для дальнейшего исследования я создал небольшой скрипт, который намеренно вызывал ошибку деления на ноль. Удивительно, что эта скриптовая задача успешно выполнилась, и исключение было правильно перехвачено блоком try/catch. Это позволило мне сделать вывод, что неожиданное поведение ограничено методом LockOneForWrite() (и его близким родственником LockOneForRead()).
Хотя я смог преодолеть эту проблему в своем конкретном приложении, используя метод Dts.VariableDispenser.Contains() для проверки существования переменной перед ее изменением, у меня все еще нет объяснения, почему исключение, вызванное методом LockOneForWrite(), не может быть перехвачено блоком try/catch.
Если вы столкнулись с подобной проблемой или у вас есть какие-либо идеи по этому вопросу, я был бы любопытен услышать ваши опыт и мысли. Пожалуйста, делитесь своими результатами в разделе комментариев ниже.
Спасибо за чтение!