这是我参与11月更文挑战的第16天,活动详情查看:2021最后一次更文挑战
翻译参考
本文主要参考翻译自 The Stairway to Integration Services
系列文章的 Control Flow Task Errors – Level 9 of the Stairway to Integration Services,目的在于对 SSIS 有一个全面清晰的认识,所有内容在原文的基础上进行实操,由于版本差异、个人疑问等多种原因,未采用完全翻译的原则,同时也会对文中内容进行适当修改,希望最终可以更有利于学习和了解 SSIS,
感谢支持!
在本篇中,我们通过使用 MaximumErrorCount
和 ForceExecutionResult
属性检查任务执行状态管理的方法来介绍容错能力(fault tolerance
)。还会学习 SSIS 控制流任务错误(SSIS Control Flow task errors
)、事件处理程序(event handlers
) 和 容器(containers
) 之间的关系。
关于SSIS任务错误
打开 “Precedence.dtsx” 包。看下”序列容器1”,右击 “Script Task 4” 点击 “启用”。
按 “F5” 执行 SSIS 包,询问 “Script Task 4” 的提示框中点击”否”,使其失败。”Script Task 2” 提示框点击 “是”,然后 “Script Task 3” 显示 完成(completed) 消息框。点击”确定”,确认消息框后,界面显示如下:
“Script Task 4” 失败是因为点击“否”按钮。为什么”序列容器1”也失败呢?
事件”冒泡”(Events “Bubble”)
错误是一个事件和事件冒泡。
点击 dtsx
中的 “包资源管理器”(Package Explorer) 标签页,然后展开”Package\可执行文件\序列容器 1\可执行文件\节点”(Package\Executables\Sequence Container 1\Executables\node)
“Script Task 4” 失败并引起一个错误事件。随后将错误事件”向上”(up the line
)发送到序列容器1。由于在序列容器1中发生了错误,它也失败了(并变成红色)。错误事件在“范围内”(up in scope
)的这种传输有时被称为“冒泡”。
错误事件不会在 序列容器1 处停止;它再次冒泡到 Precedence程序包,该程序包也失败。
从 Package Explorer 树形视图中可视化冒泡的一种方法是想象错误事件”爬树(爬树形视图)”。
错误事件的默认行为是导致任务或容器失败,并在控制流中变为红色的原因。下面看一下如何控制默认行为。
MaximumErrorCount 属性
所有的任务,包括”Script Task 4”,都有一个 MaximumErrorCount 属性。该属性默认值为1,表示一个单个错误将导致任务(task)失败。
你可以将该属性设置为99,当执行包时,”Script Task 4” 失败时,序列容器1仍会失败,没有任何改变。
原因是,MaximumErrorCount
属性是设计被容器(containers)使用的,也就是在 任务(task) 上设置 MaximumErrorCount
属性是无效的。
如下,是在 “序列容器1” 上设置 “MaximumErrorCount” 属性为99的效果:
“序列容器1”成功。
通常,一个包在发生错误时需要执行失败。偶尔,也会忽略错误(忽略错误最简单的理由是,忽略错误不会阻塞事件的处理)。通过设置 MaximumErrorCount
属性为0,可以忽略容器错误。
ForceExecutionResult 属性
另一个使”序列容器1”成功的方式是,设置容器的 ForceExecutionResult
属性(默认值为”None”)。
重设 “MaximumErrorCount” 属性为默认值1,修改序列容器1的 “ForceExecutionResult” 属性为”Success”。
调试运行SSIS包,在提示框中设置 “Script Task 4” 失败,”Script Task 2” 成功(失败也可以),最终,”序列容器1” 不会失败。
“序列容器1”成功,即使 “MaximumErrorCount” 属性设置为默认的1,”ForceExecutionResult”属性会覆”MaximumErrorCount”属性。
错误事件(Error Events
)
每次一个控制流任务失败,都会引发一个错误事件。
引发错误事件时,错误事件(error event
)属性将被填充,并且错误事件触发时,事件消息以静态的方式”沿树向上”传输(transmitted "up the tree"
)。
创建错误事件处理程序
下面,在 “Script Task 4” 上,通过向 脚本任务(Script Task) 添加 “错误事件处理程序”(OnError Event Handler
) 查看一些错误事件属性。
首先,点击控制流中的 “Script Task 4”,然后,点击 “事件处理程序”(Event Handlers
) 标签页
“事件处理程序” 选项卡打开,默认显示的是未给在控制流中选择的任务配置 OnError 事件处理程序,如图14所示:
点击可执行文件下拉列表(Executable dropdown
),可以导航到其他SSIS包的可执行文件。
在 事件处理程序下拉列表(Event Handler dropdown
) 中,可以选择希望创建的 事件处理程序(Event Handler
)。
可执行下拉列表 选择 “Script Task 4”,事件处理程序下拉列表 选择 “OnError”,点击下面的 “点击此处为可执行文件“Script Task 4”创建一个“OnError”事件处理程序”(Click here to create an ‘OnError’ event handler for executable ‘Script Task 4’
)
点击链接创建一个OnError事件处理程序,查看下事件处理程序的SSIS工具箱,它也是控制流的工具箱,也就意味着 事件处理程序提供SSIS工作流响应事件。同时事件处理程序也包括一系列事件作用域的变量(这些都是系统变量,需要在”网格选项”中设置显示)。
事件处理程序中使用变量
拖拽一个 脚本任务(Script Task
) 到 OnError事件处理程序 界面,打开 脚本任务编辑器,设置 “ScriptLanguage” 属性为 “Microsoft Visual C# 2010”。点击 “ReadOnlyVariables” 属性,然后点击 值文本框 的省略号,在“选择变量窗口”,选择变量 System::ErrorCode
、 System::ErrorDescription
和 System::SourceName
。
点击“确定”,关闭“选择变量窗口”,脚本页显示如下:
点击 “编辑脚本”(Edit Script) 按钮,打开脚本代码编辑器,Main()
中输入如下内容:
1 | cs复制代码public void Main() |
代码首先创建三个变量 —— iErrorCode、sErrorDescription 和 sSourceName,每个变量获取的是 OnError事件处理程序 相关的 SSIS变量。
获取(或映射)分为两步。第一步设置 ReadOnlyVariables 属性,将 SSIS变量 暴露给脚本任务。第二步是 Dts 命名空间中的 Variables 对象,它可以访问脚本任务 ReadOnlyVariables 属性中列出的变量集合。
在 C#
中获取SSIS变量的语法如下:
1 | cs复制代码Dts.Variables["<Variable Name>"].Value |
变量名(Variable Name
)区分大小写。
Dts.Variables
变量的 Value 属性是一个对象,这意味着我们必须转换对象到其他的数据类型,比如String 或 Integer。
脚本任务错误(Script Task Errors
)
如果脚本(C#
中)不能在脚本任务的 “ReadOnlyVariables” 属性中找到 SSIS变量,将会抛出类似下面的错误:
错误: 0xC0014054,位于 脚本任务: 无法锁定变量“System::ErrorCod”进行读访问,错误为 0xC0010001“找不到变量。如果在包的执行期间试图从容器的 Variables 集合检索某个变量,但该变量不在此处时,将出现这种情况。变量可能已更改名称,或者并未创建。”
Error: Failed to lock variable “System::ErrorCod” for read access with error 0xC0010001 “The variable cannot be found. This occurs when an attempt is made to retrieve a variable from the Variables collection on a container during execution of the package, and the variable is not there. The variable name may have changed or the variable is not being created.”.
上面的错误可以通过删除 脚本任务的”ReadOnlyVariables”属性 中列出的 System::ErrorCode
变量名中的”e”产生。通过右击”脚本任务”并点击”执行任务”执行。
任务(Task)执行失败,错误消息也可以在 “进度”(Progress,或执行结果 —— Execution Results) 标签页中看到
These errors are tedious to troubleshoot.
这些错误很难解决。(这些错误进行故障排除是很乏味的)
更正脚本任务属性中”ErrorCode”的拼写。一个快速的单元测试(unit test
) —— 在OnError事件处理程序中执行 “脚本任务”,应该会出现类似下面的结果
现在已经准备好测试 “Precedence.dtsx” SSIS包中的错误。
观察错误(Observing an Error)
执行前面的 SSIS 包,”Script Task 4” 提示框中点击”否”,这样 “Script Task 4” 失败并引发一个错误事件。这个错误事件被 OnError事件处理程序(OnError event handler) “监听者” “听到”,导致 事件处理程序 中的”脚本任务”执行并显示错误信息。如下:
更多关于冒泡(Bubbling)
之前,我们提到事件“冒泡”。在这种情况下,在 “Script Task 4” 生成的Error事件将在SSIS包的范围内 “向上传输”(“up the tree”..to
) 到 “序列容器1”。如果我们为 序列容器1 配置OnError事件处理程序,我们可以观察到这种情况的发生。
如果调试器正在运行则停止。
在 控制流 中,选择”序列容器1”,点击 “事件处理程序” 标签页。和之前一样,点击链接,为”序列容器1”创建一个OnError事件处理程序。从 “Script Task 4” 的OnError事件处理程序中复制 “脚本任务”,粘贴到 “序列容器1” 的 OnError事件处理程序 中。
打开粘贴的”脚本任务”编辑并点击”编辑脚本”按钮。修改 Main 函数中如下行:
1 | cs复制代码var sSubComponent = "序列容器1 OnError Event Handler"; |
注:暂时无法获取绑定当前事件的 task 的名字,测试了多种方法均不行,目前能获取的是 源task 名字(发生错误的任务,事件冒泡时就无法获知绑定事件处理程序的任务名了)、当前任务的名字(即当前事件处理程序中的”脚本任务”的名字)
右击当前的 “脚本任务”,点击 “执行任务”,会看到如下的执行结果。
通过 调试器执行 进入 SSIS包,”Script Task 4” 询问成功的提示框中点击 “否”,生成来自 “Script Task 4” 的错误事件。事件处理程序作为一个事件的监听者执行它的函数 —— “听到”并响应 “Script Task 4” 错误事件。
可以很方便的从消息框的 Title标题 中分辨出它是 “Script Task 4” 的 OnError事件处理程序。
点击”确定”按钮,确认消息框。错误事件然后冒泡到 “序列容器1” 的 OnError事件处理程序中
同样,你可以从消息框的 title标题 中分辨出它是 “序列容器1” 的事件处理程序。
注意消息框的内容,错误事件的源是 “Script Task 4”,并且 “Error Description” 和 “Error Code” 都没有改变。对于 SSIS 中的事件,这是非常有趣的行为。当SSIS任务最初引发事件时,将填充事件属性。一旦将事件放置在 消息总线(messaging bus
) 上,这些值就不会更改。
该事件将继续从 “序列容器1” 冒泡到 “Precedence.dtsx” 包。同时 变量值 将保持静态,通知任何关于此错误配置的监听器。
总结
本篇中,我们查看了 SSIS控制流 任务错误行为,包括 错误事件(Error events
)、OnError事件处理程序(OnError event handlers
) 和 错误冒泡(error bubbling
)。
同时还了解了事件冒泡和容器之间的关系,也介绍了 MaximumErrorCount
和 ForceExecutionResult
属性的容错能力。
本文转载自: 掘金