Web 系統需限制同一帳號同時僅能單點登入。傳統在使用者表加 IsLoggedIn 欄位,異常斷電導致旗標未重置,造成使用者無法登入。利用 **全域暫存表 (##Table) 隨連線中斷自動清理** 特性,可完美解決此問題。
CREATE PROCEDURE dbo.CheckUserLogin
@UserID VARCHAR(20),
@IsLoggedIn BIT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @TableName NVARCHAR(50) = N'##Login_' + @UserID;
DECLARE @SQL NVARCHAR(MAX);
IF OBJECT_ID('tempdb..' + @TableName) IS NULL
BEGIN
-- 首次登入:建立全域暫存表標記在線
SET @SQL = N'CREATE TABLE ' + @TableName + N' (UserID VARCHAR(20)); INSERT ' + @TableName + N' VALUES (@uid);';
EXEC sp_executesql @SQL, N'@uid VARCHAR(20)', @UserID;
SET @IsLoggedIn = 0; -- 允許登入
END
ELSE
BEGIN
-- 已有表存在 → 該帳號正在線
SET @IsLoggedIn = 1; -- 拒絕登入
END
END
CheckUserLogin @UserID, @IsLoggedIn OUTPUT。@IsLoggedIn = 1 → 回傳「該帳號已在線,請先登出」。@IsLoggedIn = 0 → 驗證密碼、建立 Session、寫入登入日誌。##),UserID 過長時需雜湊縮短。DROP TABLE ##Login_...。sp_getapplock 序列化。單機方案無法跨節點共享狀態。叢集環境建議改用 **Redis Set (SETNX)** 或 **資料庫表 + 分散式鎖** 實現單點登入。
全域暫存表「隨連線生命週期自動清理」的特性,以極簡代碼解決單機單點登入的異常殘留旗標難題,是輕量級 Web 系統的實用技巧。