在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
本文转自悦光阴博客园博客,原文链接:http://www.cnblogs.com/ljhdo/p/5125140.html,如需转载请自行联系原作者