18

我正在使用CONTEXT_INFO將用戶名傳遞給用於審計/歷史記錄表的刪除觸發器。我試圖理解CONTEXT_INFO的範圍,如果我正在創建潛在的競爭條件。SQL Server中CONTEXT_INFO的作用域是什麼?

我的每個數據庫表都有一個存儲proc來處理刪除。刪除存儲的proc將userId作爲參數,並將CONTEXT_INFO設置爲userId。我的刪除觸發器會抓取CONTEXT_INFO並使用它來更新一個審計表,指示誰刪除了行。

問題是,如果兩個刪除不同用戶的sprocs同時執行,可以將其中一個sprocs中的CONTEXT_INFO設置爲由另一個sproc觸發的觸發器消耗嗎?

我看過這篇文章http://msdn.microsoft.com/en-us/library/ms189252.aspx但我不清楚SQL Server中會話和批處理的範圍,這對於文章的幫助很有幫助!

我會發布代碼,但目前時間很短。如果不夠清楚,我會稍後再編輯。

在此先感謝您的幫助。

回答

26

上下文信息沒有範圍(在語言變量範圍的意義上)並且綁定到會話生存期。設置後,上下文信息保持在設置的值直到連接關閉(會話終止)或直到設置新值。由於會話執行是總是順序,所以不存在併發問題。

如果您在過程中設置了上下文信息,則隨後在該會話上執行的任何觸發器都將看到新設置的上下文信息值。根據您的建議在上下文信息中設置用戶標識值並在觸發器中使用它是上下文信息使用的典型示例,並且在併發性方面非常安全,因爲基本上沒有併發性。如果你打算在一個存儲過程中設置上下文信息,然後在由於刪除上述過程中發生的觸發器而依賴它的情況下,那麼你的批量還沒有完成,根據你鏈接的文章,來自sys.dm_exec_requests DMV或來自CONTEXT_INFO()函數的conetxt信息。它不會被推入sys.dm_exec_sessions,只有在您退出存儲過程並完成發送到服務器的T-SQL批處理中的任何其他調用('請求')後纔會發生這種情況。

6

我已經在一個客戶端網站使用了這種確切的方法進行審計,並且他們已經在近6個月時間內大量使用它,而且沒有任何問題。

上下文信息的範圍爲當前連接的當前批次以及在當前批次完成後啓動的任何批次。你的環境中的兩個用戶要麼不在同一個連接上,要麼在連接共享的情況下,如果它們重疊,它們仍然會有自己的值。如果一個接一個接着一個,那麼第二個會覆蓋第一個,但無論如何,它會完成它。至少這是我對它是如何工作的理解。您可以查看MARS(多個活動結果集)以獲取更多信息。