一文读懂mybatis连接池原理

news2024/11/20 11:28:12

本文需要配合代码demo一起观看更佳,源码地址。

本源码中对 mybatis代码做了详尽的注释。对mybatis源码进行了详尽的注释,且可以对项目进行install,然后在ron-man-mybatis1项目中 src/main/java/iron/man/lyf/ironmanmybatis1/run_test/MybatisQuickStart.java 进行运行 对mybatis源码进行debug查看运行过程,欢迎大家下载指正。如果您觉得帮助到您麻烦给个赞

一、概述

  1. datasource下的两个包一个是不使用连接池、一个是使用mybatis提供的连接池

    • 连接池:src/main/java/org/apache/ibatis/datasource/pooled
    • 非连接池:src/main/java/org/apache/ibatis/datasource/unpooled
  2. 此dataSource是使用的工厂模式创建的。

    1. 抽象工厂: DataSourceFactory是抽象工厂

    2. 具体工厂:pooledunpooled两个包中的UnpooledDataSourceFactoryPooledDataSourceFactory 是抽象工厂的两个实现类。PooledDataSourceFactory继承了UnPooledDataSourceFactory。两个类基本一模一样,只不过PooledDataSourceFactory中实例化的是PooledDataSourceUnPooledDataSourceFactory中实例化的是UnPooledDataSource。所以会看到在使用mybatis默认连接池的时候,却会时常调用UnPooledDataSourceFactory的方法。实际是由于UnPooledDataSourceFactory继承了UnPooledDataSourceFactory全部方法的缘故

    3. 抽象产品:工厂要生产的对象的抽象类是jdk 的 /javax/sql/DataSource

    4. 具体产品:pooledunpooled两个包中 的UnpooledDataSource、PooledDataSource 是jdk 的 DataSource 的两个实现类

  3. 可以把DataSource 的实现类看做一个手写的jdbc连接数据库的实现类(iron-man-mybatis/iron-man-mybatis1/src/main/java/iron/man/lyf/ironmanmybatis1/run_test/JdbcDemo.java)

    1. 尤其UnpooledDataSource中,只不过是把driver、url、username、password…这些连接参数提成了成员变量,由程序从配置文件读取然后给这些变量赋值。然后就是构造器多了一点,还有一些get、set方法干扰。最后就是initializeDriver加载驱动、doGetConnection从jdk拿去数据库链接Connection,与JdbcDemo的数据库连接无异。
    2. PooledDataSource 会把 UnpooledDataSource 放到属性中,是为了重复使用UnpooledDataSource中的driver、url、username、password…这些字段。PooledDataSource会存一些 最大活跃连接数最大闲置连接数等这些固定的值,而 PoolState 属性会存程序运行起来的一些值,譬如:空闲的连接池资源集合活跃的连接池资源集合等。值得注意的是PoolState.toString()会返回当前连接池的一堆关键参数

二、执行流程(以mybatis的PooledDataSource连接池为例)

  1. 每创建一个sqlSession就会进行一次数据库连接操作。由:iron-man-mybatis/iron-man-mybatis1/src/main/java/iron/man/lyf/ironmanmybatis1/run_test/CacheTest.java#Test1LevelCache 可得知。此demo创建了两个sqlsession,进行了两次数据库连接。

  2. 在src/main/java/org/apache/ibatis/datasource/pooled/PooledDataSource.java 类中的popConnectionpushConnectionpingConnection方法点断点,结合demo:CacheTest.java#Test1LevelCache 即可看到连接池运行的全貌

  3. popConnection是负责在开启一个新的sqlsession需要一个数据库连接的时候弹出来一个数据库连接。其中还会操作idleConnections(空闲的连接池资源集合)activeConnections(活跃的连接池资源集合)等状态。

  4. pushConnection是在关闭sqlsession,需要把这个数据库连接归还连接池时候进行调用。期间也会操作idleConnections(空闲的连接池资源集合)activeConnections(活跃的连接池资源集合)等状态。

  5. pingConnection是在popConnection时需要有一个验证当前连接是否有效,如果在mybatis 的配置文件 environments属性中配置了 poolPingEnabled为true,那么就会在pingConnection进行一个数据库查询的操作,查询的sql是在environments属性中配置的 poolPingQuery 的sql。

  6. /datasource/pooled/PooledConnection.java 是用对Connection做的一个动态代理增强。

    其主要作用是:

    • 保存了 jdk给的 realConnection的这个连接。
    • 在执行 sqlsession.close时 在invoke方法中 增强,来在close前执行 pushConnection 方法。

三、popConnection执行流程(从连接池中拿去一个连接)

注意点:

  1. 第一次执行popConnection的时候空闲连接肯定为0,所以会直接创建一个连接
  2. popConnection内创建的PooledConnection只是一个外壳,真正的connection 是PooledConnection内部的 realConnection
  3. 不管是怎么得到的一个连接,都会重新设置checkoutTimestamp为当前时间,这个值在超时判断中起决定作用
  4. 当一个连接超时后,需要移除一个连接时,移除的只是PooledConnection外壳,真正的realConnection不会移除只是放到新创建的PooledConnection新的外壳中。

在这里插入图片描述

四、pushConnection执行流程(归还连接池一个连接)

在这里插入图片描述

五、连接池总结:

  1. 当来一个连接请求会先看连接池有没有空闲的连接,有的话直接返回空闲连接。

  2. 如果没有空闲连接。

    1. 判断当前活跃的连接数是否到了最大连接数

      1. 未达到则直接创建一个连接(此连接是从数据库拿一个真正的连接)
      2. 已达到则判断现在的活跃的连接是否有超时的连接
        1. 如果有超时连接。则把以前的事务回滚,把超时的连接扒掉旧的PooledConnection外壳,拿到真正的realConnection,创建一个新的PooledConnection,把realConnection放进去。
        2. 如果没有超时连接,那么调用wait方法阻塞等待
  3. 验证连接

  4. 如果验证通过,那么进一步初始化PooledConnection。并修改一些状态值
    2. 如果验证不通过,即连接无效。那么badConnectionCount(累计的获取无效连接次数+1)

    • 如果重试次数超过阈值,则报错。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/159336.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

亚马逊云科技启示录:创新作帆,云计算的征途是汪洋大海

开篇:创新是亚马逊云科技发展的最持久驱动力云计算,新世纪以来最伟大的技术进步之一,从2006年 Amazon Web Service 初创时的小试牛刀,到如今成长为一个巨大的行业和生态,已经走过16年的风雨历程。Java之父詹姆斯高斯林…

关于子查询

1、什么是子查询: select语句中嵌套select语句,被嵌套的select语句称为子查询。 2、子查询都可以出现在什么地方: select ..(select) #子查询可以出在select后面 from ..(select) #子查询可以出在from后面 where ..(select) …

操作系统考研复习(详细指导)--持续更新中

第一章操作系统的概念(定义)功能和目标操作系统的概念(定义)--什么是操作系统操作系统是指控制和管理整个计算机系统的硬件和软件资源(操作系统是系统资源的管理者),并合理地组织调度计算机的工作和资源的分配;以提供给用户和其他软件方便的接口和环境 &…

【Rtklib入门指南】1. Rtklib下载及编译

写在前面其实前几年还在校的时候出过一个还不太成熟的教程,回头看的时候发现有诸多不够成熟的地方,如今的工作自由时间相对较多,因此萌生了重新梳理,提升博客质量的想法。因此,就有了这个新的系列。对于大多数GNSS的从…

JMeter - 下载安装教程

目录1. JMeter介绍2. JMeter下载3. JMeter目录解析4. Windows和macOS下安装启动5. JMeter切换语言为中文6. Linux下安装启动1. JMeter介绍 JMeter是目前行业内用的比较多的一个开源性能测试工具,由Java语言编写,要依赖Java环境来运行(需要提…

vtk.js中引入.module.css文件

我们知道css modules指的是所有的类名和动画名称默认都有各自作用域的CSS文件,是在构建步骤中对CSS类名和选择器限定作用域的一种方式(类似于命名空间)。通过CSS Modules可以保证单个组件的所有样式集中在同一个地方、只应用于该组件。它可以…

React记录

UI组件库:https://mobile.ant.design/zh/ 1、‘idname’ is not defined no-undef 情景:给属性绑定属性值时,明明设置了变量,使用语法也没有错误,但是提示却说是该变量未定义。 原因:变量的值不是字符串类…

SpringCloud学习笔记 - 服务熔断降级 - Sentinel

1. sentinel简介 sentinel官方文档:https://sentinelguard.io/zh-cn/docs/introduction.html 随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点&…

【Redis】缓存击穿问题及其解决方案

【Redis】缓存击穿问题及其解决方案 文章目录【Redis】缓存击穿问题及其解决方案1. 缓存击穿概念2. 解决方案2.1 互斥锁2.1.1 互斥锁的优缺点2.1.2 互斥锁的代码实现2.2 逻辑过期2.2.1 逻辑过期的优缺点2.2.2 逻辑过期的代码实现1. 缓存击穿概念 缓存击穿:缓存击穿…

13个有趣的Python高级脚本,建议收藏

上一篇文章:整理了上千个 Python 工具库,涵盖24个大方向 没想到火了,喜欢除了收藏外,记得点赞。 每天我们都会面临许多需要高级编码的编程挑战。你不能用简单的 Python 基本语法来解决这些问题。 在本文中,我将分享…

Python针对列表进行去重、排序、大小写转换

首先我们要进行的就是列表去重 Python针对列表进行去重、排序、大小写转换1. 针对列表进行去重第一种方法是用for循环第二种方法就是列式推导法第三种方法就是set第四种方法就是用字典去重2.进行大小写转换大写转小写使用lower进行小写转换列式推导法swapcase()将字符串内的大写…

【windows环境使用gcc完美编译C/C++】

windows环境使用gcc完美编译C/C前言安装最新版的msys2安装mingw版的gcc前言 在windows使用gcc编译c,很多文章会使用Cygwin或者msys来安装gcc,并编译本地c,但编译好的.exe执行文件在其他电脑上会报找不到cygwin1.dll或找不到msys-2.0.dll的错误…

基于JavaSpringboot+vue国风汉服文化交流宣传系统

博主介绍:✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末底部获取联系🍅 精彩专栏推荐订阅收藏👇…

ArcgisPro3.0及3.0.1及3.0.2安装教程

一、获取: https://www.xsoftnet.com/share/a0XohtwU8Zz.html二、产品介绍:ArcgisPro3.0-3.0.1中文安装包下载及安装教程 ArcGisPro3.x安装教程 一、安装包结构介绍:可能你下载的安装包目录结构有所不同但是核心文件是一样的。 安装顺序&…

【SpringCloud07】SpringCloud 整合Zookeeper注册中心

1.Zookeeper注册中心 zookeeper是一个分布式协调工具&#xff0c;可以实现注册中心功能关闭Linux服务器防火墙启动zookeeper服务器zookeeper服务器取代Eureka服务器&#xff0c;zookeeper作为服务注册中心 2.服务提供者 1.新建cloud-provider-payment8004 2.POM <?xm…

(小甲鱼python)函数笔记合集二 函数(II)总结 函数的几种参数 位置参数、关键字参数、默认参数 .join()函数的用法等

一、基础复习 函数的基本用法 创建和调用函数 函数的形参与实参等等 二、函数的几种参数 1.位置参数 一般情况下实参是按照形参定义的顺序进行传递的&#xff0c;而Python中位置固定的参数我们称为位置参数。 >>> def myfunc(s,vt,o):return "".join((o…

低成本MEMS INS系统 + GNSS组合导航MATLAB仿真

感谢西工大严老师的无私奉献&#xff01;&#xff01; 低成本MEMS INS系统 GNSS组合导航MATLAB仿真感谢西工大严老师的无私奉献&#xff01;&#xff01;一、kalman参数初始化——kfinit()二、imu添加误差——imusdderr()三、imu位姿更新——insupdate()四、kalman误差方程——…

【1】K8s的组件及概念

目录 1、K8s的组件 2、组件概念 1、K8s的组件 一个kubernetes集群主要是由控制节点(master)、工作节点(node)构成&#xff0c;每个节点上都会安装不同的组件。 master: 集群的控制平面&#xff0c;负责集群的决策 ApiServer:资源操作的唯一入口&#xff0c;接收用户输入的命令…

ArcGIS基础实验操作100例--实验92以图形与表格构建趋势面

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 空间分析篇--实验92 以图形与表格构建趋势面 目录 一、实验背景 二、实验数据 三、实验步骤 &#xf…

ts实现简易观察者模式

什么是观察者模式 观察者模式能让你时刻知悉对象状态的变化的一种设计模式,是一种一对多依赖的关系,比如报纸的订阅 生活中随处可见的观察者模式(猎头与求职者): headfirst设计模式气象站案例 通知更新的方式有两种: 主题推给观察者和观察者自己去主题拉取两种方式,大部分实现…