一文读懂mybatis连接池原理
创始人
2024-05-11 02:49:05
0

本文需要配合代码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)

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

相关内容

热门资讯

【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
ASM贪吃蛇游戏-解决错误的问... 要解决ASM贪吃蛇游戏中的错误问题,你可以按照以下步骤进行:首先,确定错误的具体表现和问题所在。在贪...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...