0

我在连接管理器中使用 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 专门为 Logging 创建另一个连接管理器,但它没有奏效。

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

提前致谢

4

1 回答 1

2

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

通用控制流

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

sql日志记录

执行后,我查询日志以查看发生了什么。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 事件。

编辑

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

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

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

第三种选择

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

交易选项设置

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

鉴于上述包,我会做的是

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

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

于 2012-07-12T18:24:00.587 回答