在 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可能会删除临时表(这实际上在我的测试中发生过)。有没有最佳实践来避免这种并发问题,即在检查其存在性和随后使用它之间不会删除表?