我无法重现你的问题。根据您的描述,我认为您的包裹看起来像这样。 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 事件。
edits
您正在日志中看到第一组条目,但希望看到第二组条目。
理解为什么会这样是至关重要的交易如何运作 http://www.sqlteam.com/article/introduction-to-transactions。事务将工作语句打包成一个块,该块是all去上班或者是all将会失败。在您的事务中,包正在发出 sp_ssis_addlogentry 命令。当前事务内部无法说“使这些语句比其他语句更持久”或“将这些语句保留在当前事务之外”。全部或全无,这是交易上下文中的唯一选择。
鉴于此,您的选择要么创建第二个专用于日志记录的连接管理器,如我使用 SO_no_retain CM 所示,要么编写您自己的错误日志记录系统。我真的、真的会提倡前者,因为它是原生行为。不然你会花很多时间
第三种选择
这让我印象深刻,也许你没有意识到这一点。您不需要开始 tran /commit/rollback 模式。 SSIS 可以开箱即用地为您做到这一点。根据包运行的位置,它将需要运行 MSDTC(MS 分布式事务协调器),但简而言之,您告诉包您希望将这些组件加入到事务中,瞧,奇迹发生了,您不需要不必管理它。 SSIS 中的每个任务都有一个 TransactionOption 属性。默认情况下,设置为“支持”。
交易选项设置 http://msdn.microsoft.com/en-us/library/ms137690.aspx
-
支持的如果存在事务,则任务将加入其中。它不会启动事务。
-
Required这将启动一个事务。如果已经存在,那么它将加入该事务
-
不需要这不会启动事务,也不会加入正在进行的事务。你can通过让所需和不需要的对象尝试操作相同的资源而使自己陷入僵局,因此请注意您在做什么。
鉴于上面的包,我会做的是
- 删除协调事务的执行 SQL 任务,
- 将 RetainSameConnection 属性保留为 False
- 在控制流级别(或序列容器),我会将 TransactionOption 设置为必需
完成了,就是这样。当包运行时,“工作”会回滚,但日志记录(包括错误)仍会存在。老实说,我写的大多数包看起来都是这样的。我从来没有理由尝试控制自己的交易,因为我(也许是愚蠢的)相信交易协调员可以处理所有这些事情。不过,在使用 SSIS 的 7 年中,我没有遇到过 MSDTC 不处理它的问题。