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

Hibernate Session 管理最佳實踐:ThreadLocal 模式詳解

     編輯:Java 相關知識

為什麼需要 ThreadLocal 管理 Session?

  • SessionFactory 執行緒安全,可共享。
  • Session 非執行緒安全,包含資料庫連線、快取等狀態,多執行緒共用會導致資料錯亂。
  • 每個請求執行緒應擁有獨立 Session,避免頻繁建立/銷毀開銷。

ThreadLocal 運作原理

內部維護一個 Map,鍵為當前執行緒,值為該執行緒專屬的變數副本。get() 若無值則呼叫 initialValue() 初始化;set() 綁定新值。簡化版實作:

public class ThreadLocal {
    private final Map values = Collections.synchronizedMap(new HashMap<>());
    public T get() {
        Thread t = Thread.currentThread();
        T val = values.get(t);
        if (val == null && !values.containsKey(t)) {
            val = initialValue();
            values.put(t, val);
        }
        return val;
    }
    public void set(T val) { values.put(Thread.currentThread(), val); }
    protected T initialValue() { return null; }
}

標準 HibernateUtil 範本

public final class HibernateUtil {
    private static final SessionFactory SESSION_FACTORY = buildSessionFactory();
    private static final ThreadLocal TL_SESSION = new ThreadLocal<>();

    private static SessionFactory buildSessionFactory() {
        try { return new Configuration().configure().buildSessionFactory(); }
        catch (Throwable ex) { throw new ExceptionInInitializerError(ex); }
    }

    public static Session currentSession() throws HibernateException {
        Session s = TL_SESSION.get();
        if (s == null) {
            s = SESSION_FACTORY.openSession();
            TL_SESSION.set(s);
        }
        return s;
    }

    public static void closeSession() throws HibernateException {
        Session s = TL_SESSION.get();
        if (s != null) { s.close(); }
        TL_SESSION.set(null); // 移除引用,防記憶體洩漏
    }
}

使用建議

  • 在 Service 層或 Filter 中開啟/關閉 Session,確保一個請求一個 Session。
  • 即使目前架構無多執行緒存取 DAO,仍建議採用此模式,為未來擴展(如遷移至 Web 容器、異步處理)預留彈性。
  • 務必在 finally 區塊呼叫 closeSession(),釋放資料庫連線並清除 ThreadLocal 引用。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved