25

为了审计/历史表的目的,我正在使用 CONTEXT_INFO 将用户名传递给删除触发器。我正在尝试了解 CONTEXT_INFO 的范围以及是否正在创建潜在的竞争条件。

我的每个数据库表都有一个存储过程来处理删除。删除存储过程以 userId 作为参数,并将 CONTEXT_INFO 设置为 userId。然后我的删除触发器获取 CONTEXT_INFO 并使用它来更新审计表,该表指示谁删除了行。

问题是,如果同时执行来自不同用户的两个删除存储过程,那么其中一个存储过程中设置的 CONTEXT_INFO 是否可以被另一个存储过程触发的触发器使用?

我看过这篇文章http://msdn.microsoft.com/en-us/library/ms189252.aspx但我不清楚 SQL Server 中会话和批处理的范围,这是这篇文章有用的关键!

我会发布代码,但目前时间很短。如果这还不够清楚,我稍后会编辑。

提前感谢您的帮助。

4

2 回答 2

33

上下文信息没有范围(在语言变量范围的意义上)并且绑定到会话生命周期。设置后,上下文信息将保持设置的值,直到连接关闭(会话终止)或设置新值。由于会话上的执行始终是顺序的,因此不存在并发问题。

如果您在过程中设置上下文信息,则随后在该会话上执行的任何触发器都将看到新设置的上下文信息值。按照您的建议,在上下文信息中设置用户 id 值并在触发器中使用它是上下文信息使用的典型示例,并且在并发方面是完全安全的,因为基本上没有并发可言。如果您打算在存储过程中设置上下文信息,然后在由于上述过程中发生的删除而运行的触发器中依赖它,那么您的批处理尚未完成,因此根据您链接的文章,您检索来自sys.dm_exec_requestsDMV 或CONTEXT_INFO()函数的 conetxt 信息。它还不会被推入sys.dm_exec_sessions,只有在您退出存储过程并完成发送到服务器的 T-SQL 批处理中的任何其他调用(“请求”)后,才会发生这种情况。

于 2010-06-12T00:51:43.583 回答
6

我已经在一个客户站点使用这种精确的方法进行审计,他们已经大量使用它近 6 个月了,没有任何问题。

上下文信息的范围仅限于当前批次的当前连接以及在当前批次完成后开始的任何批次。您的环境中的两个用户要么不在同一个连接上,要么在连接共享的情况下,如果他们完全重叠,他们仍然会有自己的值。如果一个接一个接一个,那么第二个会覆盖第一个,但无论如何到那时它已经完成了。至少这是我对其工作原理的理解。您可以查找 MARS(多个活动结果集)以获取更多信息。

于 2010-06-11T19:46:22.703 回答