在MS SQL Server中,我使用全局临时表来存储客户端传递的会话相关信息,然后在触发器中使用该信息。MS SQL Server - 全局临时表的安全并发使用?
由于同一个全局临时表可以在不同的会话中使用,并且在我想写入时可能存在也可能不存在(取决于先前使用过的所有会话是否关闭),我正在做在写入之前检查全局临时表存在的基础上创建的。
IF OBJECT_ID('tempdb..##VTT_CONTEXT_INFO_USER_TASK') IS NULL
CREATE TABLE ##VTT_CONTEXT_INFO_USER_TASK (
session_id smallint,
login_time datetime,
HstryUserName VDT_USERNAME,
HstryTaskName VDT_TASKNAME,
)
MERGE ##VTT_CONTEXT_INFO_USER_TASK As target
USING (SELECT @@SPID, @HstryUserName, @HstryTaskName) as source (session_id, HstryUserName, HstryTaskName)
ON (target.session_id = source.session_id)
WHEN MATCHED THEN
UPDATE SET HstryUserName = source.HstryUserName, HstryTaskName = source.HstryTaskName
WHEN NOT MATCHED THEN
INSERT VALUES (@@SPID, @LoginTime, source.HstryUserName, source.HstryTaskName);
的问题是,我的检查表存在和MERGE
语句之间,SQL Server可能会删除临时表,如果它是使用它发生之前的所有会话中,准确的情况下关闭(这实际上发生在我的测试中)。
是否有关于如何避免这种并发问题最佳做法是,一个表没有检查它的存在和它的后续使用之间下降了吗?
感谢您的快速回答!虽然我承认我没有考虑过永久代码和临时共享存储概念,并且您给了我一些想法,但我确实有理由选择使用全局临时表: - 在我的工作中,我可以自由使用临时表,但创建真正的表必须经历一个不同的,正式的官僚过程;我尽量避免这种情况。 - 通过使用临时表,我得到了SQL Server在我没有会话使用它的情况下将其删除的优势。真正的桌子只会留在那里并继续增长。 –
@loadH。 。 。哦,唉,官僚作风和奇怪的扭曲,让事情真正完成。我完全理解。即便如此,也许有可能在一些启动操作中创建全局临时表,因此它可用于触发器。我不喜欢尝试在触发器中创建表的想法。 –