蓝凌EKP产品:Hibernate 中 SessionFactory、Session 与事务的关系

在使用 Hibernate / Spring 的项目中,

很多人会混淆 Session、Connection、Transaction 的职责,

甚至误以为「Session 关闭就等于事务提交」。

本文从 底层原理 + 生命周期 的角度,彻底梳理三者的关系,并说明:
为什么 Session 必须关闭、事务必须提交。

一、核心结论先行(给没耐心的读者)

  • SessionFactory

    • 全局唯一

    • 线程安全

    • 用来创建 Session

  • Session

    • 不是数据库连接

    • 但会 持有 一个数据库连接

    • 有明确生命周期,必须关闭

  • Transaction

    • 决定数据是否真正写入数据库

    • 只有 commit() 才算完成事务

  • Session.close() ≠ Transaction.commit()

    • Session 关闭 ≈ 连接释放

    • 未提交事务会被 回滚

二、SessionFactory 是什么?为什么它是单例

1️⃣ 定义

SessionFactory 是 Hibernate 的核心入口对象:

复制代码
SessionFactory sessionFactory;

它的职责包括:

  • 读取 Hibernate 配置

  • 管理二级缓存

  • 创建 Session

  • 管理 JDBC 资源策略

2️⃣ 特点

特性 说明
是否线程安全 ✅ 是
是否昂贵 ✅ 创建成本高
生命周期 应用级(启动 → 关闭)

👉 一个数据库通常只需要一个 SessionFactory

三、Session 是什么?它和 Connection 的真实关系

1️⃣ Session 的本质

Session 是 Hibernate 的"工作单元(Unit of Work)"

它负责:

  • 实体的持久化状态管理

  • 一级缓存

  • 脏数据检查(Dirty Checking)

  • 生成 SQL

    Session session = sessionFactory.openSession();

2️⃣ Session ≠ Connection(但会持有 Connection)

关系可以理解为:

复制代码
Session
   ↓
Connection(来自连接池)

关键点:

  • 创建 Session 时不一定占用连接

  • 第一次执行 SQL 时才从连接池获取 Connection

  • 在默认配置下:

    • 一个 Session 通常会绑定一个 Connection

四、Transaction 是什么?它才是"是否入库"的裁判

1️⃣ Transaction 的职责

Transaction 管理的是:

  • 事务边界

  • 提交(commit)

  • 回滚(rollback)

    Transaction tx = session.beginTransaction();

2️⃣ flush ≠ commit(这是常见误区)

操作 含义
flush SQL 发送到数据库
commit SQL 真正生效

没有 commit,数据不会持久化。

五、三者的完整关系图(强烈建议收藏)

复制代码
┌─────────────────────┐
│   SessionFactory    │  (应用级单例)
└─────────┬───────────┘
          │
          ▼
┌─────────────────────┐
│       Session       │  (一次会话)
│  一级缓存 / 状态管理 │
└─────────┬───────────┘
          │
          ▼
┌─────────────────────┐
│     Connection      │  (数据库连接)
│   autoCommit=false  │
└─────────┬───────────┘
          │
          ▼
┌─────────────────────┐
│    Transaction      │
│ commit / rollback   │
└─────────────────────┘

调用顺序必须是:

复制代码
commit / rollback
→ close Session
→ 连接归还连接池

六、Session 的几种关闭方式(非常重要)

1️⃣ 手动管理 Session(非 Web / Worker 场景)

复制代码
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
try {
    ...
    tx.commit();
} catch (Exception e) {
    tx.rollback();
    throw e;
} finally {
    session.close(); // 必须
}

推荐方式

2️⃣ Spring + @Transactional(推荐)

复制代码
@Transactional
public void save() {
    sessionFactory.getCurrentSession().save(entity);
}
  • Session 由 Spring 管理

  • Transaction 自动提交 / 回滚

  • 不允许手动 close Session

3️⃣ OpenSessionInViewFilter(Web 场景)

复制代码
请求开始
  打开 Session
  Service 层提交事务
请求结束
  关闭 Session

七、为什么一定要关闭 Session?(这是重点)

1️⃣ 不关闭 Session 的直接后果

  • 数据库连接不释放

  • 一级缓存无限增长

  • 数据库锁无法释放

  • 连接池耗尽

👉 工程上表现为"连接泄露"

2️⃣ 事务未提交 + Session 未关闭 = 生产事故

复制代码
conn.setAutoCommit(false);
// 执行 SQL
// 没 commit
// 没 close

结果:

  • 数据回滚

  • 连接长期占用

  • 系统逐渐卡死

3️⃣ 为什么 close 不能代替 commit?

因为 JDBC 规定:

Connection.close() 时,如果事务未提交 → 自动回滚

也就是说:

复制代码
close ≈ 清理
commit ≈ 确认

清理永远不会等于确认。

八、最佳实践总结(可作为团队规范)

  1. SessionFactory

    • 单例

    • 应用启动时创建

  2. Session

    • 有明确边界

    • 用完必须关闭

  3. Transaction

    • 必须显式提交或回滚

    • 不依赖 close

  4. Spring 项目

    • @Transactional

    • 不手动操作事务和 Session

  5. 非 Web 线程

    • 不依赖 OSIV

    • 手动管理 Session 生命周期

九、结语

Hibernate 的问题,
80% 不是 API 用错,
而是生命周期理解错。

一旦你真正搞清楚:

  • SessionFactory 的"重"

  • Session 的"短"

  • Transaction 的"严"

你会发现:

  • 事务问题少了

  • 连接泄露没了

  • 系统稳定性直接上一个台阶

相关推荐
大模型玩家七七7 小时前
证据不足 vs 证据冲突:哪个对模型更致命
数据库·人工智能·pytorch·深度学习·安全
@ chen7 小时前
Spring MVC 核心知识
java·spring·mvc
weisian1517 小时前
JVM--2-打破刻板印象:在Java中创建一个对象,一定是分配到堆内存吗?
java·开发语言·jvm·tlab·逃逸分析·标量替换
Traced back7 小时前
SQL Server数据自动清理系统最终版(C# WinForms完整源码)
数据库·c#·.net
onkel in blog7 小时前
【Java】Gradle 多模块项目实战:Spring Boot 微服务搭建全流程
java·spring boot·微服务·gradle
想要一只奶牛猫7 小时前
Spring IOC&DI(上)
java·后端·spring
cyforkk7 小时前
10、Java 基础硬核复习:多线程(并发核心)的核心逻辑与面试考点
java·开发语言·面试
鸽芷咕7 小时前
KingbaseES 统计信息深度调优:从自动收集到扩展统计,精准提升计划质量
数据库·mysql·性能优化·kingbasees·金仓数据库
-XWB-7 小时前
【Oracle】Oracle诊断系列(3/6):性能瓶颈定位——从SQL到I/O的全面分析
数据库·sql·oracle
Remember_9937 小时前
Java 工厂方法模式:解耦对象创建的优雅方案
java·开发语言·python·算法·工厂方法模式