【数据库】--- 数据库连接池的对比

本文深入解析数据库连接池的概念、运行机制及其在系统性能优化中的作用,对比分析C3P0、DBCP、TomcatJdbcPool、BoneCP、Druid等主流数据库连接池的优缺点,并提供Spring集成配置与Tomcat JNDI配置示例。

转载于:https://blog.youkuaiyun.com/fysuccess/article/details/66972554

1.数据库连接池概述
数据库连接的建立是一种耗时、性能低、代价高的操作,频繁的数据库连接的建立和关闭极大的影响了系统的性能。数据库连接池是系统初始化过程中创建一定数量的数据库连接放于连接池中,当程序需要访问数据库时,不再建立一个新的连接,而是从连接池中取出一个已建立的空闲连接,使用完毕后,程序将连接归还到连接池中,供其他请求使用,从而实现的资源的共享,连接的建立、断开都由连接池自身来管理。

数据库连接池为系统的运行带来了以下优势:昂贵的数据库连接资源得到重用;减少了数据库连接建立和释放的时间开销,提高了系统响应速度;统一的数据库连接管理,避免了连接资源的泄露。

数据库连接池运行机制:

系统初始化时创建连接池,程序操作数据库时从连接池中获取空闲连接,程序使用完毕将连接归还到连接池中,系统退出时,断开所有数据库连接并释放内存资源。

2.主流数据库连接池比较
常用的主流开源数据库连接池有C3P0、DBCP、Tomcat Jdbc Pool、BoneCP、Druid等

C3p0: 开源的JDBC连接池,实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate、Spring等。单线程,性能较差,适用于小型系统,代码600KB左右。

DBCP (Database Connection Pool):由Apache开发的一个Java数据库连接池项目, Jakarta commons-pool对象池机制,Tomcat使用的连接池组件就是DBCP。单独使用dbcp需要3个包:common-dbcp.jar,common-pool.jar,common-collections.jar,预先将数据库连接放在内存中,应用程序需要建立数据库连接时直接到连接池中申请一个就行,用完再放回。单线程,并发量低,性能不好,适用于小型系统。

Tomcat Jdbc Pool:Tomcat在7.0以前都是使用common-dbcp做为连接池组件,但是dbcp是单线程,为保证线程安全会锁整个连接池,性能较差,dbcp有超过60个类,也相对复杂。Tomcat从7.0开始引入了新增连接池模块叫做Tomcat jdbc pool,基于Tomcat JULI,使用Tomcat日志框架,完全兼容dbcp,通过异步方式获取连接,支持高并发应用环境,超级简单核心文件只有8个,支持JMX,支持XA Connection。

BoneCP:官方说法BoneCP是一个高效、免费、开源的Java数据库连接池实现库。设计初衷就是为了提高数据库连接池性能,根据某些测试数据显示,BoneCP的速度是最快的,要比当时第二快速的连接池快25倍左右,完美集成到一些持久化产品如Hibernate和DataNucleus中。BoneCP特色:高度可扩展,快速;连接状态切换的回调机制;允许直接访问连接;自动化重置能力;JMX支持;懒加载能力;支持XML和属性文件配置方式;较好的Java代码组织,100%单元测试分支代码覆盖率;代码40KB左右。

Druid:Druid是Java语言中最好的数据库连接池,Druid能够提供强大的监控和扩展功能,是一个可用于大数据实时查询和分析的高容错、高性能的开源分布式系统,尤其是当发生代码部署、机器故障以及其他产品系统遇到宕机等情况时,Druid仍能够保持100%正常运行。主要特色:为分析监控设计;快速的交互式查询;高可用;可扩展;Druid是一个开源项目,源码托管在github上。

主流连接池各项功能对比如下:

3.数据库连接池Spring集成配置与JNDI配置
下面针对每一种连接池的使用方法,在开发中如何配置给出spring集成配置和在tomcat的conf/context.xml文件中配置2种方式,限于篇幅只给出基本参数,详细参数可自行研究。

3.1 阿里Druid连接池
Maven依赖

<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>druid</artifactId>
  <version>1.0.28</version>
</dependency>

Spring集成配置方式

<!--Spring Druid 数据源配置-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <!-- 基本属性 url、user、password -->
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <!-- 配置初始化大小、最小、最大 -->
        <property name="initialSize" value="1" />
        <property name="minIdle" value="1" />
        <property name="maxActive" value="20" />
        <!-- 配置获取连接等待超时的时间 -->
        <property name="maxWait" value="60000" />
        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="60000" />
        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
        <property name="minEvictableIdleTimeMillis" value="300000" />
        <!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
        <property name="poolPreparedStatements" value="true" />
        <property name="maxPoolPreparedStatementPerConnectionSize" value="20" />
        <!-- 配置监控统计拦截的filters,去掉后监控界面sql无法统计 -->
        <property name="filters" value="stat" />
    </bean>
    Web.xml配置
     <!--druid WebStatFilter用于采集web-jdbc关联监控的数据-->
      <filter>
        <filter-name>DruidWebStatFilter</filter-name>
        <filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class>
        <init-param>
          <param-name>exclusions</param-name>
          <param-value>*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*</param-value>
        </init-param>
      </filter>
      <filter-mapping>
        <filter-name>DruidWebStatFilter</filter-name>
        <url-pattern>/*</url-pattern>
      </filter-mapping>
      <!--druid访问监控界面 /druid/index.html-->
      <servlet>
        <servlet-name>DruidStatView</servlet-name>
        <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>DruidStatView</servlet-name>
        <url-pattern>/druid/*</url-pattern>
      </servlet-mapping>

Tomcat中context.xml文件JNDI配置方式

com.alibaba.druid.pool.DruidDataSourceFactory实现了javax.naming.spi.ObjectFactory,可以作为JNDI数据源来配置
<TOMCAT_HOME>/conf/context.xml配置JNDI方式

 <Resource
         name="jdbc/MysqlDataSource"
         factory="com.alibaba.druid.pool.DruidDataSourceFactory"
         auth="Container"
         type="javax.sql.DataSource"
         driverClassName="com.mysql.jdbc.Driver"
         url="jdbc:mysql://192.168.1.233:3306/lead_oams?useUnicode=true&characterEncoding=utf-8"
         username="lead_system"
         password="password"
         maxActive="50"
         maxWait="10000"
         removeabandoned="true"
         removeabandonedtimeout="60"
         logabandoned="false"
         filters="stat"/>
 web.xml配置
 <!--MySQL数据库JNDI数据 -->
   <resource-ref>
       <description>MySQL DB Connection</description>
       <res-ref-name>jdbc/MysqlDataSource</res-ref-name>
       <res-type>javax.sql.DataSource</res-type>
       <res-auth>Container</res-auth>
   </resource-ref>
Java代码中获取JNDI数据源

  //1、初始化名称查找上下文

  Context ctx =new InitialContext();

  //2、通过JNDI名称找到DataSource

 DruidDataSource ds = (DruidDataSource)ctx.lookup("java:comp/env/jdbc/MysqlDataSource");

  //3、通过ds获取数据库连接对象

  Connectionconn = ds.getConnection();

3.2 BoneCP连接池
Maven依赖

<dependency>
  <groupId>com.jolbox</groupId>
  <artifactId>bonecp-spring</artifactId>
  <version>0.8.0.RELEASE</version>
</dependency>
Spring集成BoneCP配置方式

<!-- Spring BoneCP 数据源配置-->
    <bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
        <!-- 数据库驱动 -->
        <property name="driverClass" value="${jdbc.driver}" />
        <!-- 相应驱动的jdbcUrl -->
        <property name="jdbcUrl" value="${jdbc.url}" />
        <!-- 数据库的用户名 -->
        <property name="username" value="${jdbc.username}" />
        <!-- 数据库的密码 -->
        <property name="password" value="${jdbc.password}" />
        <!-- 检查数据库连接池中空闲连接的间隔时间,单位是分,默认值:240,如果要取消则设置为0 -->
        <property name="idleConnectionTestPeriod" value="60" />
        <!-- 连接池中未使用的链接最大存活时间,单位是分,默认值:60,如果要永远存活设置为0 -->
        <property name="idleMaxAge" value="30" />
        <!-- 每个分区最大的连接数 -->
        <property name="maxConnectionsPerPartition" value="150" />
        <!-- 每个分区最小的连接数 -->
        <property name="minConnectionsPerPartition" value="5" />
    </bean>
Tomcat中BoneCP使用JNDI配置方式

<Resource
  name="JNDIName"
  auth="Container"
  type="com.jolbox.bonecp.BoneCPDataSource"
  factory="org.apache.naming.factory.BeanFactory"
  driverClass="oracle.jdbc.driver.OracleDriver"
  username="root" 
    password="root" 
  jdbcUrl="jdbc:mysql://localhost:3306/test"
  idleConnectionTestPeriod="0"
  idleMaxAge="10"
  partitionCount="1"
  maxConnectionsPerPartition="5"
  minConnectionsPerPartition="1"
  connectionTestStatement=""
  initSQL="select 1 from dual"/>

Java代码中获取JNDI数据源

  //1、初始化名称查找上下文

  Context ctx =new InitialContext();

  //2、通过JNDI名称找到DataSource

  DataSource ds= (DataSource) ctx.lookup("java:comp/env/jdbc/MysqlDataSource");

  //3、通过ds获取数据库连接对象

  Connectionconn = ds.getConnection();

3.3 Tomcat Jdbc Pool连接池
Maven依赖

<dependency>
  <groupId>org.apache.tomcat</groupId>
  <artifactId>tomcat-jdbc</artifactId>
  <version>7.0.75</version>
</dependency>
<dependency>
  <groupId>org.apache.tomcat</groupId>
  <artifactId>tomcat-juli</artifactId>
  <version>7.0.75</version>
</dependency>
Spring集成Tomcat Jbdc Pool配置方式

<!--tomcat jdbc pool数据源配置--> 
    <bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
        <property name="poolProperties">
        <bean class="org.apache.tomcat.jdbc.pool.PoolProperties">
        <!--driverClassName url username password-->
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/test?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
        <!--jmx support-->
        <property name="jmxEnabled" value="true"/>
        <property name="testWhileIdle" value="true"/>
        <property name="testOnBorrow" value="true"/>
        <property name="testOnReturn" value="false"/>
        <property name="validationInterval" value="30000"/>
        <property name="validationQuery" value="SELECT 1"/>
        <property name="timeBetweenEvictionRunsMillis" value="30000"/>
        <!--最大连接-->
        <property name="maxActive" value="50"/>
        <!--初始化连接-->
        <property name="initialSize" value="5"/>
        <!--最长等待时间ms-->
        <property name="maxWait" value="10000"/>
        <property name="minEvictableIdleTimeMillis" value="30000"/>
        <property name="minIdle" value="10"/>
        <!--是否允许日志-->
        <property name="logAbandoned" value="false"/>
        <property name="removeAbandoned" value="true"/>
        <property name="removeAbandonedTimeout" value="60"/>
        <property name="jdbcInterceptors" value="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"/>
    </bean>
Tomcat中context.xml文件JNDI配置方式

<Resource   
    name="jdbc/test"  
    auth="Container"  
    factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"  
    testWhileIdle="true"  
    testOnBorrow="true"  
    testOnReturn="false"  
    validationQuery="SELECT 1"  
    validationInterval="30000"  
    timeBetweenEvictionRunsMillis="30000"  
    driverClassName="com.mysql.jdbc.Driver"  
    maxActive="100"  
    maxIdle="40"
    maxWait="12000"  
    initialSize="10"  
    removeAbandonedTimeout="60"  
    removeAbandoned="true"  
    logAbandoned="true"  
    minEvictableIdleTimeMillis="30000"  
    jmxEnabled="true"  
    jdbcInterceptors=  
     "org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"  
    username="root" 
    password="root" 
    type="javax.sql.DataSource"   
    url="jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8"/>      
Java代码中获取JNDI数据源

//1、初始化名称查找上下文

  Context ctx =new InitialContext();

  //2、通过JNDI名称找到DataSource

  DataSource ds= (DataSource) ctx.lookup("java:comp/env/jdbc/test");

  //3、通过ds获取数据库连接对象

  Connectionconn = ds.getConnection();

3.4 Apache DBCP连接池
Maven依赖

<dependency>
  <groupId>commons-dbcp</groupId>
  <artifactId>commons-dbcp</artifactId>
  <version>1.4</version>
</dependency>
<dependency>
  <groupId>commons-collections</groupId>
  <artifactId>commons-collections</artifactId>
  <version>3.2.2</version>
</dependency>
<dependency>
  <groupId>commons-pool</groupId>
  <artifactId>commons-pool</artifactId>
  <version>1.6</version>
</dependency>
Spring集成DBCP配置方式

 <!-- 配置dbcp数据源 -->
      <bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <!-- 池启动时创建的连接数量 -->
        <property name="initialSize" value="5"/>
        <!-- 同一时间可以从池分配的最多连接数量。设置为0时表示无限制。 -->
        <property name="maxActive" value="50"/>
        <!-- 池里不会被释放的最多空闲连接数量。设置为0时表示无限制。 -->
        <property name="maxIdle" value="10"/>
        <!-- 在不新建连接的条件下,池中保持空闲的最少连接数。 -->
        <property name="minIdle" value="3"/>
        <!-- 设置自动回收超时连接 -->  
        <property name="removeAbandoned" value="true" />
        <!-- 自动回收超时时间(以秒数为单位) -->  
        <property name="removeAbandonedTimeout" value="200"/>
        <!-- 设置在自动回收超时连接的时候打印连接的超时错误  --> 
        <property name="logAbandoned" value="true"/>
        <!-- 等待超时以毫秒为单位,在抛出异常之前,池等待连接被回收的最长时间(当没有可用连接时)。设置为-1表示无限等待。-->  
        <property name="maxWait" value="100"/>  
      </bean>
Tomcat中context.xml文件JNDI配置方式

<Resource name="/jdbc/test" 
        type="javax.sql.DataSource" 
        driverClassName="com.sybase.jdbc3.jdbc.SybDataSource" 
        url="jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8" 
        username="root" 
        password="root" 
        initialSize="5"
        maxActive="50" 
        maxIdle="10" 
        minIdle="3"
        maxWait="50000" />    
Java代码中获取JNDI数据源

//1、初始化名称查找上下文

  Context ctx =new InitialContext();

  //2、通过JNDI名称找到DataSource

  DataSource ds= (DataSource) ctx.lookup("java:comp/env/jdbc/test");

  //3、通过ds获取数据库连接对象

  Connectionconn = ds.getConnection();

3.5 C3p0连接池
Maven依赖

<dependency>
  <groupId>c3p0</groupId>
  <artifactId>c3p0</artifactId>
  <version>0.9.1.2</version>
</dependency>
Spring集成配置方式

<!-- Spring配置c3p0数据源 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <property name="jdbcUrl" value="${jdbc.url}" />
        <property name="driverClass" value="${jdbc.driverClassName}" />
        <property name="user" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <!--连接池中保留的最大连接数。Default: 15 -->
        <property name="maxPoolSize" value="100" />
        <!--连接池中保留的最小连接数。-->
        <property name="minPoolSize" value="1" />
        <!--初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
        <property name="initialPoolSize" value="10" />
        <!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
        <property name="maxIdleTime" value="30" />
        <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
        <property name="acquireIncrement" value="5" />
        <!--JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。Default: 0-->
        <property name="maxStatements" value="0" />
        <!--每60秒检查所有连接池中的空闲连接。Default: 0 -->
        <property name="idleConnectionTestPeriod" value="60" />
        <!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->
        <property name="acquireRetryAttempts" value="30" />
        <!--获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。Default: false-->
        <property name="breakAfterAcquireFailure" value="true" />
        <!--因性能消耗大请只在需要的时候使用它。Default: false -->
        <property name="testConnectionOnCheckout"  value="false" />        
    </bean>

Tomcat中context.xml文件JNDI配置方式

 <Resource 
          name="jdbc/MysqlDataSource" 
          auth="Container"
          factory="org.apache.naming.factory.BeanFactory" 
          type="com.mchange.v2.c3p0.ComboPooledDataSource"
          driverClass="com.mysql.jdbc.Driver"
          idleConnectionTestPeriod="60"
         maxPoolSize="50" 
         minPoolSize="2"
         acquireIncrement="2" 
         user="root" 
         password="root"
         jdbcUrl="jdbc:mysql://localhost:3306/test"/>    
Java代码中获取JNDI数据源

  //1、初始化名称查找上下文

  Context ctx =new InitialContext();

  //2、通过JNDI名称找到DataSource

  DataSource ds= (DataSource) ctx.lookup("java:comp/env/jdbc/MysqlDataSource");

  //3、通过ds获取数据库连接对象

  Connectionconn = ds.getConnection();

4.总结
     本文所比较的5种数据库连接池在性能方面,根据个人测试结果和参考网上资料Druid > TomcatJDBC > DBCP > C3P0,BoneCP的性能方面没有深入比较,应该和Tomcat Jdbc差不多。对于小型的系统,并发压力不大时,选择哪一种数据库连接池差别不会很大,主要考虑的应该是连接池的稳定性。当并发量较高时,一般不会选择使用DBCP和C3P0,选择Druid是较好的。本文给出了5种数据库连接池通过Spring配置和Tomcat JNDI方式配置两种方式,Spring配置一般使用单独的属性文件,每一个连接池都提供了使用代码创建的方式,使用方式也比较类似,感兴趣可以自行研究。另外连接不同的数据库时,在配置方面的差异主要在driverClass和jdbcUrl两项,优化配置项可以另行考虑。

<think>我们正在讨论数据库连接池的test-on-return配置。根据用户的问题,用户已经了解了test-while-idle,现在想了解test-on-return。我们需要详细解释test-on-return的作用、使用场景、配置方式以及与其他参数的区别。 根据引用[1],连接池的工作机制是:当应用程序需要数据库连接时,从连接池获取一个连接,使用完毕后归还连接池。在这个过程中,连接的检测可以在不同时机进行。 test-on-return的作用: 在连接被应用程序使用完毕并归还到连接池时,连接池会检测该连接的有效性。如果检测失败,连接池会销毁这个连接而不是将其放入空闲队列。 与test-while-idle和test-on-borrow的对比- test-on-borrow:在从连接池获取连接时进行检测,如果连接无效则丢弃并重新获取一个。 - test-while-idle:在连接空闲时,由后台线程定期检测空闲连接的有效性。 - test-on-return:在连接归还到连接池时进行检测。 使用场景: test-on-return适用于希望在归还连接时立即发现无效连接的场景。这样,连接池可以确保空闲连接池中的连接都是可用的。但是,它不能保证在连接被应用程序使用过程中出现的失效(因为连接在应用程序使用过程中可能失效,而归还时检测到失效会将其销毁,但应用程序已经使用完毕,所以影响不大)。 配置注意事项: 1. 需要设置validationQuery(验证SQL)来执行检测。 2. 通常,test-on-return与test-on-borrow或test-while-idle不会同时启用,因为这样会带来额外的性能开销。选择哪个取决于具体需求。 3. 如果同时启用test-on-return和test-on-borrow,那么连接在借出和归还时都会被检测,这样虽然保证了连接的有效性,但增加了两次检测的开销。 性能影响: 在连接归还时进行检测,会增加归还操作的时间,但可以及时清理无效连接,避免无效连接被再次借出。在高并发场景下,可能会对性能产生一定影响,因此需要根据实际情况权衡。 配置示例(以Druid连接池为例): ```properties # 启用归还时检测 spring.datasource.druid.test-on-return=true # 设置验证SQL spring.datasource.druid.validation-query=SELECT 1 ``` 注意:不同的连接池可能有不同的参数名称,例如: - Tomcat JDBC Pool: testOnReturn - HikariCP: 没有直接的test-on-return参数,但可以通过扩展来实现类似功能。 总结: test-on-return是连接池在连接归还时进行有效性检测的机制,它保证了归还到连接池的连接都是有效的,但增加了归还操作的开销。在配置时,需要根据应用场景选择合适的检测机制。 相关问题: 1. test-on-return和test-on-borrow同时使用会怎样? 2. 如何选择test-on-return、test-on-borrow和test-while-idle? 3. 在高并发场景下,test-on-return会对性能产生什么影响? 4. 哪些主流的连接池支持test-on-return配置? </think> ### **test-on-return 配置详解** 在数据库连接池中,**test-on-return** 是用于**验证归还连接有效性**的核心参数。其作用机制与配置逻辑如下: --- #### 1. **核心功能与触发时机** - **作用**:在连接被应用程序**归还到连接池时**,立即检测连接是否有效(如网络中断或数据库重启导致连接失效)。 - **目标**:确保连接池中的空闲连接**随时可用**,避免后续获取到已损坏的连接。 - **触发条件**:仅当调用 `connection.close()` 归还连接时触发检测[^1]。 --- #### 2. **与 test-while-idle 和 test-on-borrow 的对比** | 参数 | 检测时机 | 适用场景 | 性能影响 | |-------------------|--------------------------|----------------------------------|------------------| | **test-on-return** | 连接**归还到连接池时** | 高频归还场景(如短事务) | **中等**(归还时有额外开销) | | **test-on-borrow** | 从连接池**获取连接时** | 对连接可靠性要求极高的场景 | **高**(每次获取都检测) | | **test-while-idle**| **后台线程定期扫描**空闲连接 | 低频使用或长空闲场景 | **低**(异步检测) | > ✅ **关键区别**: > - `test-on-return` 在**归还时**检测,确保**连接池内连接有效**; > - `test-while-idle` 在**空闲时**检测,减少主动获取时的延迟; > - `test-on-borrow` 在**获取时**检测,确保立即可用性[^1][^2]。 --- #### 3. **依赖参数与配置示例** 需配合以下参数使用(以 Druid 为例): | 参数 | 说明 | 必需 | 示例值 | |---------------------|------------------------------|------|---------------| | `validationQuery` | 检测连接的 SQL 语句 | 是 | `SELECT 1` | | `testOnReturn` | 启用归还检测(默认 `false`) | 是 | `true` | **Spring Boot + Druid 配置**: ```properties # 启用归还时检测 spring.datasource.druid.test-on-return=true # 设置验证SQL spring.datasource.druid.validation-query=SELECT 1 ``` --- #### 4. **适用场景与注意事项** - **推荐场景**: - 短事务系统(连接频繁借还); - 数据库环境不稳定(如云数据库易断连)。 - **注意事项**: 1. **不替代空闲检测**:若连接归还后长时间未被使用,仍需 `test-while-idle` 兜底; 2. **性能权衡**:归还时检测增加延迟,高并发场景需谨慎启用; 3. **连接池兼容性**: - Tomcat JDBC Pool:`testOnReturn` - HikariCP:无直接支持,需通过 `idleTimeout` + `connectionTestQuery` 模拟。 --- #### 5. **工作流程示例** ```mermaid sequenceDiagram App->>ConnectionPool: 执行完毕,调用 connection.close() ConnectionPool->>Database: 发送 validationQuery (e.g., SELECT 1) alt 连接有效 Database-->>ConnectionPool: 返回成功 ConnectionPool->>Idle Queue: 归还连接 else 连接无效 Database-->>ConnectionPool: 返回失败或超时 ConnectionPool->>Connection: 销毁连接 end ``` > **总结**:`test-on-return` 是**实时保障连接池健康性**的有效手段,尤其适合高频短事务系统。建议与 `validationQuery` 配合使用,并避免与 `test-on-borrow` 同时启用以减少冗余开销[^2]。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值