1. 程式人生 > 資料庫 >基於SSIS 事件的向上傳遞(詳解)

基於SSIS 事件的向上傳遞(詳解)

在SSIS中,Package是Task元件的有序組合,具有層次結構,Package處於層次結構的頂層(Root Level),對於父子包結構,父包(Parent Package)通過Execute Package Task元件呼叫其他Package,被呼叫的Package是子包,父包是子包的上層級別,最頂層的Package,處於層次結構的頂層,叫做根包(Root Package);容器(Container)元件包含其他Task元件,容器是被包含的Task元件的父級別(Parent Level);Task元件是層次結構的最底層,處於葉級別(Leaf Level)。事件就是沿著Package的層次結構向上傳遞的。

在Package中,每一個Task元件都是一個可執行程式(Executable),所有的資料處理任務都是由Task元件完成的。在Package執行(runtime)時,SSIS引擎為了監控和追蹤Task元件的執行狀態,預先建立了12個系統事件(Event),這些事件都是在Package執行時(runtime)被可執行程式(Executable)觸發的,每個事件都會產生相應的訊息,用於描述Executable的執行狀態,供開發工程師對Package進行除錯和效能調優。一旦有事件被觸發,SSIS會執行相應的事件處理程式(Event Handler),SSIS為每個事件都建立了預設的事件處理程式,命名規範是:On+EventName,使用者可以建立自定義的事件處理程式,以擴充套件Package的功能,使Package在執行時更容易管理,以完成資料處理任務。在ETL開發中,最常用的事件是錯誤(Error)事件,該事件在Executable執行出現錯誤時觸發,對應的事件處理程式是OnError。

在Package的層次結構中,事件處理具有向上傳遞(Propagate)的特性。發生在Task元件的事件,首先會被該Task元件的Event Handler捕獲和處理;如果該Task元件沒有建立Event Handler,那麼SSIS把該Event向上傳遞到其父級別的Executable,由其父級別的Event Handler來處理;如果該Executable有Event Handler,那麼由該Event Handler負責響應和處理該事件。事件會依次向上傳遞,直到事件被處理,或者傳遞到頂層被預設處理,事件向上傳遞的頂層是根包(Root Package)。

引用MSDN官方文件的例子,Package的層次結構如下圖所示:

在層次結構中,如果相應的Task元件沒有定義事件處理程式,那麼事件向上傳遞的過程如下圖所示:

注:事件向上傳遞的條件是沒有建立自定義的事件處理程式,預設情況下,該圖示有誤,事件被Event Handler處理之後,將繼續向上傳遞,我會在下文詳細解釋。

MSDN對圖示做了說明:

If an event has no event handler,the event is raised to the next container up the container hierarchy in a package. If this container has an event handler,the event handler runs in response to the event. If not,the event is raised to the next container up the container hierarchy. Only the package has an event handler,for its OnError event. If an error occurs when the Execute SQL task runs,the OnError event handler for the package runs. 

把事件依次向上傳遞的特性,是由事件處理程式(Event Handler)的系統變數 Propagate 控制的,變數Propagate的預設值是True,這意味著,預設情況下,該事件將會被傳遞到上層級別的Event Handler中進行處理。有一個例外是在父子包結構中,子Package在進行包驗證(Validation)時,不管子包的Propagate變數的值如何設定,都會把驗證事件傳遞到父包中,父包繼續執行驗證。

當前Task元件必須建立事件處理程式,才能檢視和修改變數Propagate的值。如果把事件處理程式(Event Handler)的Propagate變數設定為False,那麼該事件只會被當前的事件處理程式處理和響應,不會被傳遞到上層級別的事件處理程式中。但是,如果沒有為“肇事”的Task元件建立事件處理程式(Event Handler),那麼事件總是向上傳遞,直到被事件處理程式響應,如果Package的層次結構沒有定義任何事件處理程式,那麼事件最終被根包(Root Package)預設處理。

一,錯誤事件處理程式(OnError)向上傳遞

預設情況下,當前Task元件的事件處理程式中把錯誤(Error)事件處理之後,SSIS引擎仍然把錯誤事件向上層事件處理程式傳遞,直到包層次結構的最頂層,如下圖,在ChildPackage的Package級別和Executable級別上分別建立了OnError事件處理程式,Executable級別是child Execute SQL Task:

執行Package,在child Execute SQL Task中觸發錯誤事件,被該Task的事件處理程式捕獲和處理,下圖是Executable級別的OnError事件處理程式,其成功執行一個Task:

但是,錯誤事件沒有停止,而是繼續向上傳遞,被其直接上級,也就是Package級別的OnError事件處理程式捕獲,如下圖,來自子Task元件的錯誤事件被父級處理之後,Package仍然報錯,錯誤訊息是:Package execution completed with error.

錯誤事件處理程式把錯誤事件(Error)向上傳遞(Propagate)的過程類似“冒泡”,從觸發錯誤事件的“肇事”Task元件開始,逐級向上傳遞到最頂層的可執行程式(Executable),最頂層的Executable是 Package 本身。這意味著,如果在Package 級別定義了一個錯誤事件處理程式(OnError),每當Package中的任意一個Task元件觸發錯誤事件(Error),最終都會觸發Package級別的錯誤事件處理程式。在父子包結構中,如果父Package通過Execute Package Task呼叫子Package,那麼,錯誤事件會發生相同的過程,子Package的錯誤事件會向上傳遞(Propagate)到父Package中。

二,禁用錯誤事件的向上傳遞

如果想要禁用事件的向上傳遞過程,可以在Task元件的事件處理程式中,把系統變數Propagate設定為False,這樣,事件將不再向上傳遞,只觸發當前Task元件的事件處理程式,只有在Task元件中建立事件處理程式之後,才能修改系統變數Propagate的預設值。

1,修改系統變數Propagate的預設值

step1,呈現系統變數

開啟Event Handlers Tab,在Variables 窗體中,點選網格選項(Grid Options)按鈕,開啟Variable Grid Options 窗體,在Filter選項中勾選"Show system variables",點選“OK”,返回到Variables窗體:

step2,設定Propagate的值

在 Variables 窗體中,找到 Propagate 系統變數(Scope是OnError),把Value設定為False

2,禁用事件處理的向上傳遞

禁用Task元件的事件處理的向上傳遞(Propagate)特性之後,在當前Task元件中觸發的事件,只會被當前Task元件的事件處理程式捕獲和處理,而不傳遞到上層Task元件的事件處理程式。

再次執行Package,由於錯誤事件是被child Execute SQL Task觸發的,其事件處理程式自動捕獲並處理該Error事件:

而Package級別的事件處理程式沒有捕獲到Error事件,Package沒有執行OnError事件處理程式,最終的執行結果是:Package execution completed with success。

三,沒有建立事件處理程式

如果沒有為Task元件建立事件處理程式(Event Handler),那麼事件總是從當前Task元件向上傳遞。使用者建立事件處理程式,並不意味著,需要在其中新增Task元件,做資料處理任務,空的事件處理程式是允許的。在空的事件處理程式中把系統變數Propagate設定為False,那麼事件將不會向上傳遞,也不會被顯式處理,錯誤訊息仍然會被SSISDB記錄,但強烈建議不要這樣做。

參考文件:

Integration Services (SSIS) Event Handlers

System Variables

以上這篇基於SSIS 事件的向上傳遞(詳解)就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。