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

Hibernate Session 線程安全管理最佳實踐:ThreadLocal 模式與 Web 過濾器集成

     編輯:Java 相關知識

核心問題

  • SessionFactory:線程安全,應用級單例
  • Session:非線程安全,請求級對象,多線程共享會導致數據混亂

通用解決方案:ThreadLocal 隔離

public class HibernateUtil {
    private static final SessionFactory sessionFactory = buildSessionFactory();
    private static final ThreadLocal threadLocal = new ThreadLocal<>();
    
    public static Session currentSession() {
        Session s = threadLocal.get();
        if (s == null) {
            s = sessionFactory.openSession();
            threadLocal.set(s);
        }
        return s;
    }
    
    public static void closeSession() {
        Session s = threadLocal.get();
        if (s != null) {
            s.close();
        }
        threadLocal.remove();  // 防止內存洩漏
    }
    
    private static SessionFactory buildSessionFactory() {
        try {
            return new Configuration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            throw new ExceptionInInitializerError(ex);
        }
    }
}

使用模式

Session session = HibernateUtil.currentSession();
User user = (User) session.get(User.class, 1);
System.out.println(user.getName());
HibernateUtil.closeSession();

Web 環境深度集成:Filter 管理事務邊界

public class HibernateSessionFilter implements Filter {
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
            throws IOException, ServletException {
        try {
            chain.doFilter(req, resp);  // 處理請求
            HibernateSessionUtil.commitTransaction();  // 提交
        } catch (Exception e) {
            HibernateSessionUtil.rollbackTransaction();  // 回滾
            throw new ServletException(e);
        } finally {
            HibernateSessionUtil.closeSession();  // 關閉 Session
        }
    }
}

事務工具類完整實現

public class HibernateSessionUtil {
    private static final ThreadLocal sessionTL = new ThreadLocal<>();
    private static final ThreadLocal txTL = new ThreadLocal<>();
    
    public static Session currentSession() { /* 同 HibernateUtil */ }
    public static void closeSession() { /* 同 HibernateUtil */ }
    
    public static void beginTransaction() {
        Transaction tx = txTL.get();
        if (tx == null) {
            tx = currentSession().beginTransaction();
            txTL.set(tx);
        }
    }
    
    public static void commitTransaction() {
        Transaction tx = txTL.get();
        if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()) {
            tx.commit();
        }
        txTL.remove();
    }
    
    public static void rollbackTransaction() {
        Transaction tx = txTL.get();
        if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()) {
            tx.rollback();
        }
        txTL.remove();
    }
}

Web.xml 配置

<filter>
    <filter-name>hibernateFilter</filter-name>
    <filter-class>com.example.HibernateSessionFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>hibernateFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

關鍵最佳實踐

  • 請求開始:HibernateSessionUtil.beginTransaction()
  • 業務代碼:HibernateSessionUtil.currentSession() 獲取 Session
  • 請求結束:Filter 自動提交/回滾並關閉 Session
  • 異常處理:確保 finally 塊關閉資源
  • 避免長事務:事務邊界盡量縮小
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved