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

Oracle 基於 Session 的全域暫存表在連線池架構下的資料殘留問題與最佳實踐

     編輯:Oracle 教學

Oracle 基於 Session 的全域暫存表在連線池架構下的資料殘留問題與最佳實踐

Oracle 全域暫存表 (GTT) 分 ON COMMIT DELETE ROWS (交易級) 與 ON COMMIT PRESERVE ROWS (Session 級)。在 WebLogic 等連線池架構中,Session 重複使用導致 Session 級 GTT 資料累積,造成邏輯錯誤與效能下降。本文分析問題根因並給出解決方案。

1. 兩類 GTT 定義對比

-- 交易級:COMMIT 即清空
CREATE GLOBAL TEMPORARY TABLE gtt_txn (id NUMBER) ON COMMIT DELETE ROWS;

-- Session 級:Session 結束才清空
CREATE GLOBAL TEMPORARY TABLE gtt_sess (id NUMBER) ON COMMIT PRESERVE ROWS;

2. 連線池場景下的問題

  • 應用伺服器 (WebLogic/Tomcat/JBoss) 維護連線池,HTTP 請求結束時 **不關閉資料庫 Session**,而是歸還池中。
  • 使用 ON COMMIT PRESERVE ROWS 的 GTT,資料在 Session 存活期間持續累積。
  • 後續請求複用該 Session 讀取到上一請求的殘留資料,導致業務邏輯錯誤。

3. 解決方案

方案 A:改用交易級 GTT (推薦)

CREATE GLOBAL TEMPORARY TABLE gtt_txn (id NUMBER) ON COMMIT DELETE ROWS;

每次事務提交自動清空,天然適配連線池模型。

方案 B:維持 Session 級但手動清理

  • 每次業務邏輯結束前顯式 TRUNCATE TABLE gtt_sess; (需 DROP ANY TABLE 權限或建立包裝程序授權)。
  • 或在連線池 close() / 檢出前執行清理邏輯 (需應用框架支援)。

方案 C:使用私有暫存表 (18c+)

CREATE PRIVATE TEMPORARY TABLE ora$ppt_my_temp (id NUMBER);

生命週期綁定交易或 Session,自動隔離、自動清理,無跨 Session 污染。

4. 最佳實踐清單

  1. 優先選擇 ON COMMIT DELETE ROWS,除非有跨事務保留資料的強需求。
  2. 若必須用 Session 級,**務必在業務代碼明確點執行 TRUNCATE**。
  3. 監控 V$TEMPSEG_USAGE 觀察暫存段使用情況,預防臨時表空間爆滿。
  4. 文檔化 GTT 類型選擇理由,納入代碼審查清單。

理解 GTT 生命週期與連線池重用機制的交互,是避免資料殘留 Bug 的關鍵。

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