【问题标题】:SSIS: Default Logging OnError don't work with RetainSameConnectionSSIS:默认日志记录 OnError 不适用于 RetainSameConnection
【发布时间】:2012-07-12 08:02:04
【问题描述】:

我在我的连接管理器中使用 RetainSameConnection=true,因为我正在使用事务(如果成功/失败,最后是 BEGIN TRANSACTION、COMMIT 或 ROLLBACK)。

我还使用默认的 SQL Server 日志记录提供程序并选择了 OnError 事件(以及其他事件)。

问题是我看不到 sysssislog 表中记录的 OnError 事件(该表存在并且创建了默认插入 SP) - 我可以看到记录的其他类型的事件。

使用 SQL 分析器,我可以检查 sp_ssis_addlogentry 是否已执行:

exec sp_executesql N'exec sp_ssis_addlogentry @P1,@P2,@P3,@P4,@P5, @P6,@P7,@P8,@P9,@P10,@P11',N'@P1 nvarchar(4000),@P2 nvarchar(4000),@P3 nvarchar(4000),@P4 nvarchar(4000),@P5 唯一标识符,@P6 唯一标识符,@P7 datetime2(7),@P8 datetime2(7),@P9 int,@P10 varbinary(8000),@P11 nvarchar(4000)', N'OnError',N'EWOIU027013096',N'ad\oiu099',N'Empty AF SINtemp','4CCEB32F-E884-483C-A02F-56D5C8438E44', '15F585B3-AC6C-476F-8A2E-FC926438AC84','2012-07-12 14:46:15','2012-07-12 14:46:15',0,0x, N'违反主键 约束“CIRNAGF0p0_AF”。不能插入重复 键入对象 ''dbo.TIRNAGF0_AF''。'

但是没有插入 OnError 事件。

当我将 RetainSameConnection 属性更改为 false 时,它​​可以工作,但是我不能依赖我的事务 SQL 任务。

注意:我什至尝试使用 RetainSameConnection=false 创建另一个专门用于日志记录的连接管理器,但没有成功。

我可以毫无问题地记录到文本文件,但我们需要记录到表中。

提前致谢

【问题讨论】:

  • 但是您的分析器确实显示 N'OnError is getting inserted 。它是否显示为另一种情况??
  • 正在回滚,请尝试使用单独的连接管理器进行日志记录
  • @praveen 我可以独立于 RetainSameConnection 值查看每种类型事件的 exec sp_executesql。
  • @msmucker0527 我已经尝试了一个单独的连接管理器来记录日志(尝试使用相同的连接字符串和一个单独的连接字符串)但没有成功;我也认为它正在回滚,但为什么其他事件类型被正确插入(PackageStart/End 和 OnPostExecute 的 Rollback 和容器)?我可以更改我的 sp_ssis_addlogentry 以打开另一个事务吗?
  • @AndreAlbuquerque 我能够成功回滚事务并使用单独的连接保留日志。主连接的 RetainSameConnection 设置为 true,而日志连接设置为 false,再试一次

标签: sql-server logging ssis onerror


【解决方案1】:

我无法重现您的问题。根据您的描述,我假设您的包裹看起来像这样。 SO_retain OLE 连接管理器指向我正在工作的数据库,并将 RetainConnection 属性设置为 True。

我添加了事件 OnError 和 OnPre/PostExecute 的日志记录。我跑了两次包裹。一次使用 SO_retain 连接管理器,一次使用 SO_no_retain。

执行后,我查询日志以查看发生了什么。 SELECT L.id, L.event, L.source, L.executionid FROM dbo.sysdtslog90 L ORDER BY 1;如果你使用的是2008/2008R2,修改表为dbo.sysssislog。

我的结果是

1   PackageStart    so_Andre_LoggingTrxn    B2D17896-199F-4213-B800-E812CE95D45F
2   OnPreExecute    so_Andre_LoggingTrxn    B2D17896-199F-4213-B800-E812CE95D45F
3   OnPreExecute    Begin tran  B2D17896-199F-4213-B800-E812CE95D45F
13  OnPostExecute   Rollback    B2D17896-199F-4213-B800-E812CE95D45F
14  OnPostExecute   so_Andre_LoggingTrxn    B2D17896-199F-4213-B800-E812CE95D45F
15  PackageEnd  so_Andre_LoggingTrxn    B2D17896-199F-4213-B800-E812CE95D45F

16  PackageStart    so_Andre_LoggingTrxn    F6898ECA-46E7-4760-8885-898FADCBEFFD
17  OnPreExecute    so_Andre_LoggingTrxn    F6898ECA-46E7-4760-8885-898FADCBEFFD
18  OnPreExecute    Begin tran  F6898ECA-46E7-4760-8885-898FADCBEFFD
19  OnPostExecute   Begin tran  F6898ECA-46E7-4760-8885-898FADCBEFFD
20  OnPreExecute    Sequence Container  F6898ECA-46E7-4760-8885-898FADCBEFFD
21  OnPreExecute    Divide by zero  F6898ECA-46E7-4760-8885-898FADCBEFFD
22  OnError Divide by zero  F6898ECA-46E7-4760-8885-898FADCBEFFD
23  OnError Sequence Container  F6898ECA-46E7-4760-8885-898FADCBEFFD
24  OnError so_Andre_LoggingTrxn    F6898ECA-46E7-4760-8885-898FADCBEFFD
25  OnPostExecute   Divide by zero  F6898ECA-46E7-4760-8885-898FADCBEFFD
26  OnPostExecute   Sequence Container  F6898ECA-46E7-4760-8885-898FADCBEFFD
27  OnPreExecute    Rollback    F6898ECA-46E7-4760-8885-898FADCBEFFD
28  OnPostExecute   Rollback    F6898ECA-46E7-4760-8885-898FADCBEFFD
29  OnPostExecute   so_Andre_LoggingTrxn    F6898ECA-46E7-4760-8885-898FADCBEFFD
30  PackageEnd  so_Andre_LoggingTrxn    F6898ECA-46E7-4760-8885-898FADCBEFFD

如您所见,事情正在按照人们对交易的预期进行。在第一次执行中,包开始触发记录的事件(PackageStart、OnPreExecute)。源“Begin tran”的 OnPreExecute 是我们看到的最后一件事,直到“Rollback”的 OnPostExecute 触发。但是,ID 之间存在差距。该间隙是在事务下发生的所有插入。该事务被回滚,因此所有这些工作都被撤消,唯一的指标是消耗的身份值。

当我将日志记录更改为使用 SO_no_retain 作为连接管理器时,我看到正在记录 OnError 事件。

编辑

您在日志中看到了第一组条目,但希望看到第二组。

了解为什么会这样是how transactions work 的基础。事务将工作声明打包成一个all 会起作用或all 会失败的东西。在您的事务中,程序包正在发出 sp_ssis_addlogentry 命令。当前事务内部没有办法说“使这些语句比其他语句更持久”或“在当前事务之外保留这些语句”。全有或全无,这是交易上下文中的唯一选择。

鉴于此,您可以选择创建第二个专用于日志记录的连接管理器,正如我在 SO_no_retain CM 中展示的那样,或者编写您自己的错误日志记录系统。我真的,真的会提倡前者,因为它是原生行为。否则,您将花费大量时间

第三个选项

这件事让我印象深刻,也许你没有意识到这一点。您不需要 begin tran /commit/rollback 模式。 SSIS 可以为您开箱即用地做到这一点。根据包运行的位置,它需要运行 MSDTC(MS 分布式事务协调器),但简而言之,你告诉包你想让这些组件加入一个事务,瞧,奇迹发生了,你不需要不必管理它。 SSIS 中的每个任务都有一个 TransactionOption 的属性。默认情况下,它设置为支持。

TransactionOption settings

  • 支持如果存在事务,则任务将加入其中。它不会启动事务。
  • 必需 这将启动一个事务。如果一个已经存在,那么它将加入该事务
  • NotRequired 这不会启动事务,也不会参与正在进行的事务。您可以通过尝试操作相同资源的必需对象和非必需对象来使自己陷入僵局,因此请注意自己在做什么。

鉴于上面的包,我会做的是

  1. 删除协调事务的执行SQL任务,
  2. 将 RetainSameConnection 属性保留为 False
  3. 在控制流级别(或序列容器),我会将 TransactionOption 设置为必需

完成,就是这样。当包运行时,“工作”被回滚,但日志记录,包括错误,将在那里。老实说,我写的每个包看起来都差不多。我从来没有理由尝试控制我自己的交易,因为我可能愚蠢地相信交易协调员会处理所有这些。不过,在与 SSIS 合作的 7 年中,我没有遇到过 MSDTC 不处理它的问题。

【讨论】:

  • 这正是正在发生的事情(我的 SSIS 包看起来和你的一模一样)。我们需要 OnError 日志,即使它们被回滚。我可以使用 sp_ssis_addlogentry 中的另一个事务来完成此操作吗?
  • 我记得读过它,但认为它是另一个依赖项(MSDTC)。 MSDTC 默认执行吗?当我在本地运行时,我必须手动启动服务。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-23
  • 2019-01-07
  • 2014-11-23
  • 2018-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多