数据库 connection 跟 session 的概念

数据库 connection 跟session 的概念

数据库连接(Connection)和会话(Session)是数据库交互中的两个核心概念,它们密切相关但又有明确的区别。

数据库连接(Connection)

数据库连接是应用程序与数据库服务器之间的物理通信通道(如 TCP 连接)。它通过驱动建立,常见的驱动有jdbc,连接负责传输 SQL 语句和返回结果。

为提高性能,常用连接池复用连接,避免频繁打开关闭连接。
配置示例:

# Druid 连接池配置
#连接池初始化时创建的 物理连接数量
spring.datasource.druid.initial-size=5  
#连接池中始终保持的 最小空闲连接数。
spring.datasource.druid.min-idle=5
#连接池支持的 最大活跃连接数
spring.datasource.druid.max-active=20
#从连接池获取连接时 最大等待时间(单位:毫秒),超时后抛异常
spring.datasource.druid.max-wait=60000
#用于检测连接是否有效的 验证 SQL 语句,如果执行失败,连接会被丢弃并重建
spring.datasource.druid.validation-query=SELECT 1
#检测连接有效性是否启用,Druid 会对空闲连接定期检查(默认每隔 1 分钟),确保连接池中的连接可用
spring.datasource.druid.test-while-idle=true
#每次获取连接时都会执行 validation-query,确保连接有效,默认 false,频繁检测会影响性能
spring.datasource.druid.test-on-borrow=false
# 是否在归还连接时检测其有效性,确保连接未被破坏
spring.datasource.druid.test-on-return=false 

会话(Session)

会话是数据库服务器为单个客户端连接创建的逻辑工作环境,用于跟踪和管理用户的操作状态。
每个会话独立,操作不会直接影响其他会话(除非显式提交事务)。

会话与连接的关系

ession 的生命周期会受到 Connection 的控制,在 Connection 连接关闭或超时终止,Session 被销毁,当连接被连接池回收时,重置 Session 的状态,而不是销毁。

会话与事务的关系

Session 是事务的载体,一个 Session 可以串行执行多个事务。

Mybatis 的 Sqlssion 是怎么管理session 的
创建SqlSession:

通过SqlSessionFactoryopenSession()方法创建SqlSession实例。
在创建过程中,MyBatis会加载配置文件,建立数据库连接等。

执行数据库操作:
使用SqlSessionselectOne()selectList()insert()update()delete()等方法执行SQL语句。
MyBatisSQL语句映射为Java对象,执行数据库操作,并处理结果。

事务管理:
SqlSession支持事务管理,可以通过commit()方法提交事务,或通过rollback()方法回滚事务。

关闭SqlSession:
完成数据库操作后,应调用SqlSessionclose()方法关闭SqlSession。
关闭SqlSession会释放数据库连接等资源,避免资源泄露。

部分源码说明 SqlSessionInterceptor

  private class SqlSessionInterceptor implements InvocationHandler {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      SqlSession sqlSession = getSqlSession(SqlSessionTemplate.this.sqlSessionFactory,
          SqlSessionTemplate.this.executorType, SqlSessionTemplate.this.exceptionTranslator);
      try {
        Object result = method.invoke(sqlSession, args);
        if (!isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) {
          // force commit even on non-dirty sessions because some databases require
          // a commit/rollback before calling close()
          sqlSession.commit(true);
        }
        return result;
      } catch (Throwable t) {
        Throwable unwrapped = unwrapThrowable(t);
        if (SqlSessionTemplate.this.exceptionTranslator != null && unwrapped instanceof PersistenceException) {
          // release the connection to avoid a deadlock if the translator is no loaded. See issue #22
          closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
          sqlSession = null;
          Throwable translated = SqlSessionTemplate.this.exceptionTranslator
              .translateExceptionIfPossible((PersistenceException) unwrapped);
          if (translated != null) {
            unwrapped = translated;
          }
        }
        throw unwrapped;
      } finally {
        if (sqlSession != null) {
          closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
        }
      }
    }
  }
  • 对于自动提交的事务,每条sql 是独立的事务,调用一次mapper里的方法将会新建一个 sqlSession 来执行方法。

  • 同一事务中 不管调用多少次 mapper里的方法 ,最终都是用得同一个 sqlSession,即一个事务中使用的是同一个sqlSession,底层是由 ThreadLocal 保证的。
    TransactionSynchronizationManager
    private static final ThreadLocal<Map<Object, Object>> resources = new NamedThreadLocal("Transactional resources");

  • 如果没有开启事务,调用一次mapper里的方法将会新建一个 sqlSession 来执行方法。

总结

使用连接池时,多个 HTTP 请求可能共享同一物理连接,但每个请求会绑定到独立会话(通过重置会话状态实现隔离)。

连接是物理层面的,可以类比为马路,关注 传输效率(如网络延迟、带宽),会话是逻辑层面, 关注的是操作正确性,可以类比为车。
举一个生活中的示例:

Connection 就像你和客服之间的电话线路(物理通道);
负责传输声音(数据),线路本身不记录对话内容;
如果挂断电话(关闭连接),线路会被释放。

Session 就像客服的工作台(逻辑环境):
记录当前对话的上下文(如你的账户信息、问题进展等);
如果线路保持畅通(连接未关闭),客服可以处理你的多个请求(多个事务);
如果换人接听(连接池复用),新客服会重置工作台(清理前一次会话状态);
如果电话线拆了(连接关闭),工作台也就不要了(销毁会话状态)。

参考:

https://juejin.cn/post/6844904002421800967

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值