从另一个会话/连接放弃存储的proc执行

时间:2012-07-24 15:48:36

标签: sql-server tsql stored-procedures

我有一个昂贵的存储过程,它在表中的数据发生变化后运行,以便预先计算这些数据的某些聚合。 (SP应用程序调用,而不是通过表中的触发器调用,如果这是相关的,尽管这不是一个硬性要求)。存储过程几乎完全是INSERT INTO ... SELECT语句。

数据通常不经常更改(即SP调用很少),但它们原则上可以重叠。为了确保在这种情况下的一致性,我使用sp_getapplock,以便第二次调用将在继续之前等待第一次调用完成。

这有效,但等待效率低且不必要 - 我的存储过程首先要做的是删除所有现有(现在已过时)的数据。我真正想要的是第二次调用告诉第一个“不要打扰你正在做的事情,事情现在已经改变 - 只是停止运行,我会把事情保持在正确的状态”。

在这种情况下,第二次调用是否有可靠的方法可靠地中止第一次SP调用?

2 个答案:

答案 0 :(得分:3)

每次更改后,您真的需要重新聚合吗?

将后续更新推迟到正在进行的更新是否足够好?

即使您可以打断它,也必须等待它回滚交易,这可能需要比等待它完成更长的时间。

答案 1 :(得分:2)

没有办法优雅地做到这一点。如果对一个语句发出'kill',则可以使该语句的连接处于未知状态。此外,正如@GilM正确地指出(+1) - 回滚可能需要比完成更长的时间,具体取决于执行的阶段。

所以这是一个你可能没有想过的建议。您是否考虑过使用索引视图?您可以在标准版中使用它们,但是您需要使用WITH (NOEXPAND)提示查询它们以获得收益。但是,您可以简单地将该视图包装在包含提示的另一个视图中。

这样你就可以用一些非常好的好处取代整个过程:

  • 它完全透明地为您更新。
  • 它比'重新聚合整套'效率更高。