Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 SSIS ограничить итерации цикла по времени выполнения  [new]
IDVT
Member

Откуда:
Сообщений: 313
Всем привет. Подскажите пожалуйста.

Есть пакет, в одном цикле выполняется множество действий над данными (Извлечение, трансформация и вставка данных). Мне необходимо ограничить выполнение каждой итерации по времени, т.е. если итерация цикла превысила определенное значение в секундах, то необходимо прервать выполнение и перейти к следующему шагу цикла.

Пытался сделать это имитируя ошибку в компоненте SriptTask, итерация останавливается только после завершения выполнения любого контейнера (если он запустился до фиксации исключения в SriptTask), я не знаю, как мне прервать все активные действия принудительно. Остается только перечислить их в том же SriptTask и проверять на активность, если активен, то принудительно останавливать. Может есть более правильное решение?
7 мар 18, 13:30    [21243140]     Ответить | Цитировать Сообщить модератору
 Re: SSIS ограничить итерации цикла по времени выполнения  [new]
Andy_OLAP
Member

Откуда: я знаю, что Хапоэль Беэр-Шева - чемпион
Сообщений: 3151
IDVT
Пытался сделать это имитируя ошибку в компоненте SriptTask

There are limitations in using the Script Task having no control over other tasks after its execution turn
Периодически всплывает такая задача. Пока общепринятая придумка только вторым sql agent job контролировать время первого agent job с пакетом SSIS внутри и гасить по превышению лимита.
Заказ в Редмонд для лимита времени вроде как есть, но воз и ныне там.
7 мар 18, 14:26    [21243355]     Ответить | Цитировать Сообщить модератору
 Re: SSIS ограничить итерации цикла по времени выполнения  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31331
Andy_OLAP
Заказ в Редмонд для лимита времени вроде как есть, но воз и ныне там.
Не, заказа нет.
Из Редмонда пишут в этих обсуждениях: "если надо - заказывайте в коннекте". Видимо, никто не заказал.
7 мар 18, 14:39    [21243400]     Ответить | Цитировать Сообщить модератору
 Re: SSIS ограничить итерации цикла по времени выполнения  [new]
Andy_OLAP
Member

Откуда: я знаю, что Хапоэль Беэр-Шева - чемпион
Сообщений: 3151
alexeyvg
Andy_OLAP
Заказ в Редмонд для лимита времени вроде как есть, но воз и ныне там.
Не, заказа нет.
Из Редмонда пишут в этих обсуждениях: "если надо - заказывайте в коннекте". Видимо, никто не заказал.

Я отвлекся на проблему прикручивания нового движка в postgresql и перестал пинать этих ленивых индусов. Спасибо за информацию.
7 мар 18, 14:47    [21243432]     Ответить | Цитировать Сообщить модератору
 Re: SSIS ограничить итерации цикла по времени выполнения  [new]
Дедушка
Member

Откуда: Город трёх революций
Сообщений: 5111
IDVT,

отказаться от цикла в ссис и перейти на внешний
далее как вам уже посоветовали гасить пакет и стартовать новый
7 мар 18, 14:52    [21243453]     Ответить | Цитировать Сообщить модератору
 Re: SSIS ограничить итерации цикла по времени выполнения  [new]
IDVT
Member

Откуда:
Сообщений: 313
Так в том и дело, тушить джоб не есть решение, жаль что выхода нет.... Значит буду колхозить =(
7 мар 18, 14:52    [21243455]     Ответить | Цитировать Сообщить модератору
 Re: SSIS ограничить итерации цикла по времени выполнения  [new]
Критик
Member

Откуда: Москва / Калуга
Сообщений: 33515
Блог
используем самописаное веб-приложение, которое стартует SSIS-пакеты, и убивает их после превышения заданного в приложении времени выполнения
7 мар 18, 15:50    [21243606]     Ответить | Цитировать Сообщить модератору
 Re: SSIS ограничить итерации цикла по времени выполнения  [new]
StarikNavy
Member

Откуда: Москва
Сообщений: 2394
>>которое стартует SSIS-пакеты, и убивает их после
аналогично, но просто соседним джобом, который сверяет время работы основного джоба, с опорной таблицей, где прописаны ограничения
7 мар 18, 16:43    [21243711]     Ответить | Цитировать Сообщить модератору
 Re: SSIS ограничить итерации цикла по времени выполнения  [new]
.Евгений
Member

Откуда:
Сообщений: 498
IDVT
Всем привет. Подскажите пожалуйста.

Есть пакет, в одном цикле выполняется множество действий над данными (Извлечение, трансформация и вставка данных). Мне необходимо ограничить выполнение каждой итерации по времени, т.е. если итерация цикла превысила определенное значение в секундах, то необходимо прервать выполнение и перейти к следующему шагу цикла.

Пытался сделать это имитируя ошибку в компоненте SriptTask, итерация останавливается только после завершения выполнения любого контейнера (если он запустился до фиксации исключения в SriptTask), я не знаю, как мне прервать все активные действия принудительно. Остается только перечислить их в том же SriptTask и проверять на активность, если активен, то принудительно останавливать. Может есть более правильное решение?

Запилил себе такое решение.
А именно - таймер в работающем script task, который принудительно гасит соединение с источником данных.
7 мар 18, 18:04    [21243853]     Ответить | Цитировать Сообщить модератору
 Re: SSIS ограничить итерации цикла по времени выполнения  [new]
IDVT
Member

Откуда:
Сообщений: 313
Что-то я совсем потерялся и запутался, выручайте .....

Смысл таков: Родительский пакет, запускает N'ое количество дочерних пакетов, (работаю на прямую с файлов DTSX). Добавил счетчик, по достижению которого, мне необходимо убить поток, не дожидаясь его завершения.

Функция загрузки файла DTSX дочернего пакета

+
        static void RunPackage( int NumFlowsExecute
                              , int NumRepetition
                              , int NumSession
                              , object SourceDataList
                              , string DTSXPackage
                              , string StageDBName
                              , string DWHDBName
                              , ref Boolean ExceptionFlow)
        {
            Application app = new Application();
            Package pkg = app.LoadPackage(DTSXPackage, null);
            Variables vars = pkg.Variables;
                      vars["User::NumFlowsExecute"].Value = NumFlowsExecute;
                      vars["User::SourceDataList"].Value = SourceDataList;
                      vars["User::NumRepetition"].Value = NumRepetition;
                      vars["User::NumSession"].Value = NumSession;
                      vars["User::StageDBName"].Value = StageDBName;
                      vars["User::DWHDBName"].Value = DWHDBName;
             pkg.Execute(null, vars, null, null, null);

            if (pkg.ExecutionResult.ToString() == "Failure")
            {
                ExceptionFlow = true;
            }
        }


Формирование задач (потоки)

+
var TasksFlow = new List<Thread>();      
.
.
.
                for (int i = 0; i < CountRunFlow; i++)
                {
                    int NumFlowsExecute = i + 1;
                    var Thread = new Thread(() => RunPackage(NumFlowsExecute
                                                           , NumRepetition
                                                           , NumSession
                                                           , DTableList
                                                           , DTSXPackage
                                                           , StageDBName
                                                           , DWHDBName
                                                           , ref ExceptionFlow));
                    Thread.Start();
                    TasksFlow.Add(Thread);
                }


проверка на завершение потоков, тут вызываю метод Abort() каждому активному патоку, т.е. не завершенному, срок выполнения которых превысил допустимый (переменная TimeOutDTSXPackage)

+
            while( TasksFlow.Any(t => t.ThreadState == System.Threading.ThreadState.Running))
            {
                CounterSec ++;

                // поток(и) выполняется дольше допустимого времени (сек)
                if( CounterSec > TimeOutDTSXPackage) 
                  {
                   
                    for ( int i = 0; i < CountRunFlow; i ++)
                       {
                         var CurrentThread = TasksFlow.ElementAt(i);
                         // проверка состояния потока
                         if( CurrentThread.ThreadState == System.Threading.ThreadState.Running)
                           {
                             CurrentThread.Abort(); //если активен, то завершаем поток
                           }
                       }
                  }
                Thread.Sleep(1000);
            }

            Dts.Variables["User::ExceptionFlow"].Value = ExceptionFlow;
            Dts.TaskResult = (int)ScriptResults.Success;


Скрипт, по заданному условию замечательно выходит из цикла, вся дальнейшая логика работает, НО метод Abort() на самом деле не завершает дочерний пакет. Наверняка я криво описал логику его завершения, нет навыков работы с C#, тем более с потоками. Помогите пожалуйста убить все не завершенные потоки в списке "TasksFlow".

Методы решения с Джобом мне не совсем подходит, т.к. количество потоков задается переменной, сегодня 2, завтра 14 и т.д.
12 мар 18, 13:07    [21249419]     Ответить | Цитировать Сообщить модератору
 Re: SSIS ограничить итерации цикла по времени выполнения  [new]
ryukl
Guest
https://stackoverflow.com/questions/12207684/how-do-i-terminate-a-thread-in-c11

How do I terminate a thread ?
12 мар 18, 13:26    [21249527]     Ответить | Цитировать Сообщить модератору
 Re: SSIS ограничить итерации цикла по времени выполнения  [new]
.Евгений
Member

Откуда:
Сообщений: 498
IDVT
Что-то я совсем потерялся и запутался, выручайте .....

Могу ошибиться, но, во-первых, вы завершаете не выполнение пакета, а локальный поток, запустивший пакет на сервере. Во-вторых, выполняемый пакет нельзя завершить принудительно - можно лишь вежливо попросить его завершиться (это не джоба).
Именно по этой причине для принудительного останова пакета я и рвал его соединение с источником.
12 мар 18, 13:57    [21249682]     Ответить | Цитировать Сообщить модератору
 Re: SSIS ограничить итерации цикла по времени выполнения  [new]
Ferdipux
Member

Откуда: Москва
Сообщений: 552
IDVT,

А у вас SSIS версии 2008 или 2012+? Если 2012+ и пакеты в режиме SSIS Catalog - их можно запускать асинхронно, получая назад код исполнения. Далее - периодически проверять статус определенного экземпляра исполнения. Если необходимо - исполнение можно прибить.

Пример - см http://muxtonmumbles.blogspot.ru/2012/08/programmatically-executing-packages-in.html
Подробная информация о namespace - https://msdn.microsoft.com/en-us/library/microsoft.sqlserver.management.integrationservices.aspx

Если же у вас SSIS 2008 - то через jobs, если динамически - можно создать job и затем его прибить.
12 мар 18, 14:21    [21249783]     Ответить | Цитировать Сообщить модератору
 Re: SSIS ограничить итерации цикла по времени выполнения  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4683
IDVT,
Этот метод должен без проблем решить поставленную задачу. Thread.Join Method (TimeSpan)

https://msdn.microsoft.com/en-us/library/23f7b1ct(v=vs.110).aspx
12 мар 18, 14:26    [21249806]     Ответить | Цитировать Сообщить модератору
 Re: SSIS ограничить итерации цикла по времени выполнения  [new]
Andy_OLAP
Member

Откуда: я знаю, что Хапоэль Беэр-Шева - чемпион
Сообщений: 3151
Ferdipux
IDVT,

А у вас SSIS версии 2008 или 2012+? Если 2012+ и пакеты в режиме SSIS Catalog - их можно запускать асинхронно, получая назад код исполнения.

Добавлю, что дефолтно они как раз асинхронно и запускаются.
И нужно для синхронности делать нечто подобное:
	declare @execution_id bigint
 	exec [SSISDB].[catalog].[create_execution] 
		@folder_name = N'folder1'
		,@project_name = N'project1'
		,@package_name = package1.dtsx'
		,@execution_id = @execution_id output
	exec [SSISDB].[catalog].[set_execution_parameter_value]
		@execution_id,  
		@object_type=50, 
		[b]@parameter_name=N'SYNCHRONIZED', [/b]
		@parameter_value=1; -- true
	exec [SSISDB].[catalog].[start_execution] @execution_id
	set @output_execution_id = @execution_id
12 мар 18, 14:46    [21249877]     Ответить | Цитировать Сообщить модератору
 Re: SSIS ограничить итерации цикла по времени выполнения  [new]
Andy_OLAP
Member

Откуда: я знаю, что Хапоэль Беэр-Шева - чемпион
Сообщений: 3151
Andy_OLAP,

Так красивее:
declare @execution_id bigint
 	exec [SSISDB].[catalog].[create_execution] 
		@folder_name = N'folder1'
		,@project_name = N'project1'
		,@package_name = N'package1.dtsx'
		,@execution_id = @execution_id output
	exec [SSISDB].[catalog].[set_execution_parameter_value]
		@execution_id,  
		@object_type=50, 
		[b]@parameter_name=N'SYNCHRONIZED', [/b]
		@parameter_value=1; -- true
	exec [SSISDB].[catalog].[start_execution] @execution_id
	set @output_execution_id = @execution_id
12 мар 18, 14:48    [21249885]     Ответить | Цитировать Сообщить модератору
 Re: SSIS ограничить итерации цикла по времени выполнения  [new]
IDVT
Member

Откуда:
Сообщений: 313
Версия сервера 2016, полностью позволяет уйти от листинга под 2008 версию, но переписывать достаточно много, пока нет на это время. Поэтому, большинство предложенных решений не совместимо с текущим проектом, сейчас дочерний пакет даже не развернут на сервер, загружается из локальной директории. Но все это перепишу в ближайшее время, а решение требуется сейчас.

a_voronin
IDVT,
Этот метод должен без проблем решить поставленную задачу. Thread.Join Method (TimeSpan)

https://msdn.microsoft.com/en-us/library/23f7b1ct(v=vs.110).aspx


Спасибо, попробую. Но не совсем понимаю полезности, мне необходимо грубо завершить дочерний пакет, в данном примере проверка на его завершение. С этим отлично справляется метод List.Any(t => t.ThreadState == System.Threading.ThreadState.Running)
12 мар 18, 15:18    [21250004]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить