蓝凌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 的"严"

你会发现:

  • 事务问题少了

  • 连接泄露没了

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

相关推荐
蜗牛互联网5 小时前
从Barclays扩大Claude部署看受监管软件工程的责任重分配
java·大数据·人工智能·后端·软件工程
天远API5 小时前
零信任架构实战:基于天远股权穿透构建自动化供应链授信穿透网关
java·人工智能·架构·自动化
最强小杰5 小时前
claude-opus-5.5 API 接入教程:anthropic-version 头、tools 定义、流式事件格式三个常见问题全部梳理,收藏备用
java·服务器·网络·ai
Cc.Y5 小时前
Java零基础入门:方法(函数)深度掌握
java·开发语言
2501_933670795 小时前
2027届大数据管理与应用求职数字化转型顾问:项目、SQL、业务理解怎么排优先级
数据库·sql
奋发向前wcx5 小时前
CSP-J复赛模拟赛1 王晨旭补题 2026.10.2
java·开发语言
卓怡学长6 小时前
w192基于springboot“考研情报站”微信小程序设计与实现
java·spring boot·spring·微信小程序·intellij-idea
东方护航数据恢复(深圳)6 小时前
物流案例:勒索病毒 Mallox 加密 ERP 数据库,旧备份 + 残留页重组实录【东方护航数据恢复深圳店】
数据库·数据恢复·勒索病毒·二次开盘·开盘·数据镜像
wuminyu6 小时前
JEP491中synchronized关键字引发的平台线程钉住解决方法简介
java·linux·c语言·jvm·c++
.Hypocritical.6 小时前
Redis从入门到实战:核心原理、场景落地与避坑指南
数据库·redis·缓存