首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 擴展預存程序安全開發指南:引用計數管理 DLL 生命週期與執行緒安全陷阱

     編輯:關於SqlServer

核心挑戰:DLL 載入進程空間,全域變數僅初始化一次

擴展預存程序本質是 DLL,載入 SQL Server 進程空間後,LoadLibrary 僅增加引用計數,全域/靜態變數不會重新初始化。若忽略此特性,多次呼叫初始化函數會導致資源洩漏或狀態錯亂。

解決方案:引用計數模式

HINSTANCE hInst = NULL;
int nRef = 0;

SRVRETCODE xp_part_init(SRV_PROC* p) {
  if (nRef == 0) {
    hInst = LoadLibrary("part.dll");
    // 取得 Init 函數指標並呼叫...
  }
  ++nRef;
  return XP_NOERROR;
}

SRVRETCODE xp_part_finalize(SRV_PROC* p) {
  if (nRef == 0) return XP_NOERROR;
  if (--nRef == 0) {
    // 呼叫 Fin 釋放資源
    FreeLibrary(hInst); hInst = NULL;
  }
  return XP_NOERROR;
}

執行緒區域儲存 (TLS) 的誤區

嘗試用 TLS 隔離使用者狀態(每位使用者獨立初始化/清理)失敗,因 SQL Server 使用執行緒池,同一使用者的多次呼叫可能分派給不同執行緒,TLS 無法保證同一邏輯連線對應同一執行緒。

結論與最佳實務

  • 採用進程級引用計數管理 DLL 載入/卸載與資源初始化/釋放。
  • 呼叫端必須嚴格配對 xp_part_init / xp_part_finalize,否則會造成狀態不一致。
  • 避免在擴展預存程序中維護使用者級狀態;若必要,改由應用層或 CLR 整合實作。

擴展預存程序運行於 SQL Server 核心進程,穩定性與安全性容錯極低。引用計數雖非完美,但在現有架構下是相對可控的資源管理模式;TLS 因執行緒池機制而失效,開發者務必謹記。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved