在資料庫應用中,CRUD(建立/讀取/更新/刪除)是基石。單機時代單一應用獨佔資料庫,CRUD 操作相對安全;進入網路時代,多客戶端並存存取同一資料庫,傳統 CRUD 面臨資料不一致、髒讀、幻讀等併發問題。事務正是解決此類問題的關鍵機制,確保一組操作要么全成功、要么全失敗(回滾),維護資料完整性。本文分三部分深入探討 Hibernate 事務管理:會話與事務關係、核心 API、實戰範例與 ThreadLocal 模式。
會話代表客戶端與伺服器從登入到登出的完整互動週期。一個會話可包含多個事務。
事務是不可分割的原子操作單位,包含一或多條 SQL 陳述式。特性遵循 ACID:
事務邊界:BEGIN TRANSACTION 開始,COMMIT 提交或 ROLLBACK 回滾結束。
Java 應用透過 JDBC(Socket)與資料庫通訊。JDBC 預設 autoCommit=true,每條 SQL 獨立提交。事務管理本質是將 autoCommit 設為 false,手動控制提交/回滾時機。
| 介面/類別 | 核心方法 | 說明 |
|---|---|---|
SessionFactory | openSession() | 建立會話,通常為單例,執行緒安全。 |
Session | beginTransaction(), getTransaction(), save(), update(), delete(), close() | 會話核心介面,非執行緒安全,對應一個資料庫連線。 |
Transaction | commit(), rollback(), setTimeout() | 事務介面,封裝底層 JDBC/JTA 事務。 |
SessionContext | currentSession() | 管理當前執行緒綁定的會話,支援 ThreadLocal 模式。 |
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
// 業務邏輯:CRUD 操作
session.save(entity);
tx.commit();
} catch (RuntimeException e) {
if (tx != null) tx.rollback();
throw e;
} finally {
session.close();
}
public void transfer(Account from, Account to, double amount) {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
try {
from.setBalance(from.getBalance() - amount);
to.setBalance(to.getBalance() + amount);
session.update(from);
session.update(to);
tx.commit();
} catch (Exception e) {
tx.rollback();
throw new RuntimeException("轉帳失敗", e);
} finally {
session.close();
}
}
為避免在 DAO 層重複開關會話,常用 ThreadLocal 將會話綁定至當前執行緒,實現「一請求一會話」:
public class HibernateUtil {
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<>();
private static final SessionFactory sessionFactory = buildSessionFactory();
public static Session getCurrentSession() {
Session session = threadLocal.get();
if (session == null || !session.isOpen()) {
session = sessionFactory.openSession();
threadLocal.set(session);
}
return session;
}
public static void closeSession() {
Session session = threadLocal.get();
threadLocal.remove();
if (session != null && session.isOpen()) session.close();
}
}
搭配 Servlet Filter 或 Spring 的 OpenSessionInViewFilter,在請求開始時開啟會話,結束時自動提交/回滾並關閉,極大簡化事務管理程式碼。
Hibernate 事務管理核心在於:理解會話與事務的生命週期、熟練掌握 Session/Transaction API、善用 ThreadLocal 模式實現請求級會話綁定。正確的事務邊界劃分與異常處理,是構建高併發、高可靠資料庫應用的基石。