如何创建无法回滚效果的存储过程?

时间:2011-09-12 16:53:19

标签: sql-server tsql stored-procedures transactions

我希望有一个存储过程将记录插入tableA并更新tableB中的记录。

将从触发器中调用存储过程。

即使触发器的最外层事务被回滚,我希望tableA中的插入记录存在。

tableA中的记录是线性链接的,我必须能够重建线性连接。

只能通过触发器对tableA进行写访问。

我该怎么做?

3 个答案:

答案 0 :(得分:9)

您正在寻找的是自治事务,而今天SQL Server中并不存在这些事务。请对以下项目进行投票/评论:

http://connect.microsoft.com/SQLServer/feedback/details/296870/add-support-for-autonomous-transactions

http://connect.microsoft.com/SQLServer/feedback/details/324569/add-support-for-true-nested-transactions

你可以考虑做的是使用xp_cmdshell或CLR来回到SQL引擎之外(SQL Server无法回滚这些操作)......但这些方法并非没有自己的问题。

另一个想法是使用INSTEAD OF triggers - 您可以记录/更新其他表,然后决定不继续执行实际操作。

修改

根据@ VoodooChild的建议,您可以使用@table变量暂时保存回滚后可以引用的数据 - 这些数据将在回滚后继续存在,而不是插入{{1} }。

答案 1 :(得分:5)

请参阅此帖子Logging messages during a transaction以获得(有点复杂)实现所需内容的有效方法:即使事务已回滚,也会保留对日志记录表的插入。 Simon提出的方法有几个优点:不需要对调用者进行任何更改,速度快且可扩展,并且可以在触发器内安全使用。 Simon的例子是用于记录,但插入可以用于任何事情。

答案 2 :(得分:4)

一种方法是创建指向本地服务器的链接服务器。通过链接服务器执行的存储过程将不会回滚:

EXEC LinkedServer.DbName.dbo.sp_LogInfo 'this won''t be rolled back'

您可以从触发器调用远程存储过程。