c3p0连接池,当数据源不可用时 自动跳过

时间:2022-08-26 13:03:47

最近在一个项目中出现一个问题:

系统使用spring+c3p0管理数据库的连接池,项目中一共用到了4个数据源。在启动项目时,如果其中有某一个或几个数据源连不上时,后台就会无限次尝试连接,导致整项目无法启动。


而实际上,我们想要的结果是,如果某个数据源无法连接使用时,跳过该数据源的连接,继续加载下面的项目。于是查了一下c3p0连接池配置,发现经过如下配置后即可达到理想的效果。

在数据源配置时,加上如下三项内容:

<property name="breakAfterAcquireFailure" value="true" />
<property name="checkoutTimeout" value="100"/>
<property name="acquireRetryAttempts" value="0"/>

其中:

  • checkoutTimeout:当连接池用完时客户端调用getConnection()后等待获取新连接的时间,超时后将抛出 SQLException,如设为0则无限期等待。单位毫秒。Default: 0 
  • breakAfterAcquireFailure :true表示pool向数据库请求连接失败后标记整个pool为block并close,就算后端数据库恢复正常也不进行重连,客户端对pool的请求都拒绝掉。false表示不会标记 pool为block,新的请求都会尝试去数据库请求connection。默认为false。因此,如果想让数据库和网络故障恢复之后,pool能继续请求正常资源必须把此项配置设为false
  • acquireRetryAttempts:定义在从数据库获取新连接失败后重复尝试的次数。Default: 30

最后,一个完整的数据源配置如下:

<bean id="iamsDB" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${iamsDB.driverClass}" />
<property name="jdbcUrl" value="${iamsDB.url}" />
<property name="user" value="${iamsDB.user}" />
<property name="password" value="${iamsDB.password}" />
<property name="maxPoolSize" value="${iamsDB.maxPoolSize}" />
<property name="minPoolSize" value="${iamsDB.minPoolSize}" />
<property name="maxIdleTime" value="${iamsDB.maxIdleTime}" />
<property name="initialPoolSize" value="${iamsDB.initialPoolSize}" />
<property name="acquireIncrement" value="${iamsDB.acquireIncrement}" />
<property name="maxStatements" value="${iamsDB.maxStatements}" />
<property name="idleConnectionTestPeriod" value="${iamsDB.idleConnectionTestPeriod}" />
<property name="acquireRetryAttempts" value="${iamsDB.acquireRetryAttempts}" />
<property name="breakAfterAcquireFailure" value="true" />
<property name="checkoutTimeout" value="100"/>
<property name="acquireRetryAttempts" value="0"/>
</bean>