在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对图示做了说明:
把事件依次向上传递的特性,是由事件处理程序(Event Handler)的系统变量 Propagate 控制的,变量Propagate的默认值是True,这意味着,默认情况下,该事件将会被传递到上层级别的Event Handler中进行处理。有一个例外是在父子包结构中,子Package在进行包验证(Validation)时,不管子包的Propagate变量的值如何设置,都会把验证事件传递到父包中,父包继续执行验证。
当前Task组件必须创建事件处理程序,才能查看和修改变量Propagate的值。如果把事件处理程序(Event Handler)的Propagate变量设置为False,那么该事件只会被当前的事件处理程序处理和响应,不会被传递到上层级别的事件处理程序中。但是,如果没有为“肇事”的Task组件创建事件处理程序(Event Handler),那么事件总是向上传递,直到被事件处理程序响应,如果Package的层次结构没有定义任何事件处理程序,那么事件最终被根包(Root Package)默认处理。
默认情况下,当前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
以上这篇基于SSIS 事件的向上传递(详解)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持编程之家。