datasource - c3p0 连接池是否确保最大池大小?

标签 datasource connection-pooling c3p0

我经历了几个问题,this 有点相关,但没有回答我的问题。
c3p0连接池maxPoolSize是否保证某个时间的连接数永远不会超过这个限制?如果 maxPoolSize=5 和 10 个用户完全同时开始使用该应用程序会怎样?
我的应用程序。配置

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass"><value>${database.driverClassName}</value>/property>
    <property name="jdbcUrl"><value>${database.url}</value></property>
    <property name="user"><value>${database.username}</value></property>
    <property name="password"><value>${database.password}</value></property>
    <property name="initialPoolSize"><value>${database.initialPoolSize}</value>/property>
    <property name="minPoolSize"><value>${database.minPoolSize}</value></property>
    <property name="maxPoolSize"><value>${database.maxPoolSize}</value></property>
    <property name="idleConnectionTestPeriod"><value>200</value></property>
    <property name="acquireIncrement"><value>1</value></property>
    <property name="maxStatements"><value>0</value></property> 
    <property name="numHelperThreads"><value>3</value></property>
</bean>

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource"/>              
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
    <property name="dataSource" ref="dataSource"/>
</bean>

最佳答案

区分数据源和连接池很重要。

maxPoolSize 由 c3p0 在每个池的基础上强制执行。但是单个 DataSource 可能拥有多个连接池,因为每组身份验证凭据都有(并且必须)一个不同的池。如果只调用了默认的 dataSource.getConnection() 方法,则 maxPoolSize 将是池获取和管理的最大连接数。但是,如果使用 dataSource.getConnection( user, password ) 获取连接,则 DataSource 最多可容纳 (maxPoolSize * num_distinct_users) 连接。

回答您的具体问题,如果 maxPoolSize 是 5 并且 10 个客户端同时访问 c3p0 数据源,则其中不超过 5 个将首先获得连接。其余客户端将 wait() 直到连接返回(或 c3p0.checkoutTimeout 已过期)。

一些警告:c3p0 强制执行 maxPoolSize,如上所述。但不能保证,即使只使用了一个 per-auth 池,您偶尔也不会看到超过 maxPoolSize 的连接被 check out 。例如,c3p0 过期并异步销毁连接。就 c3p0 而言,一旦 Connection 对客户端不可用并标记为销毁,而不是在它实际被销毁时​​,它就会消失。因此,如果 maxPoolSize 为 5,您可能偶尔会在数据库中观察到 6 个打开的连接。池中将有 5 个连接处于事件状态,而第 6 个连接正在等待销毁但尚未销毁。

您可能会意外看到许多连接打开的另一种情况是,如果您在运行时修改连接池属性。实际上,内部连接池的配置是不可变的。当您在运行时“更改”池参数时,实际发生的是使用新配置启动新池,而旧池进入“结束”模式。从旧池中 checkout 的连接仍然有效且有效,但当它们 checkin 时,它们将被销毁。只有当所有旧池连接都被重新 checkin 时,池才真正死亡。

因此,如果您有一个已 check out maxPoolSize 连接的池,然后更改配置参数,您可能会暂时看到高达 (2 * maxPoolSize) 的峰值,如果新池在从旧池中 check out 的连接之前被大量流量击中被退回。在实践中,这很少是一个问题,因为动态重新配置不是那么常见,并且连接 check out 应该并且通常非常简短,因此旧池连接迅速消失。但它可能发生!

我希望这有帮助。

ps acquireIncrement 最好设置为大于 1 的值。acquireIncrement 的 1 意味着没有连接在需求之前被预取,因此每当负载增加时,一些线程将直接体验连接获取的延迟。

关于datasource - c3p0 连接池是否确保最大池大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16932846/

相关文章:

java - Hibernate 在 1 天后无法执行查询

sql-server - Grails dbCreate ='validate' 无法识别现有表

python - 理解 python 中的数据库连接池

mysql - NodeJS + mysql : using connection pool leads to deadlock tables

mysql - glassfish 空闲超时后数据库连接不会释放

jdbc - createArrayOf AbstractMethodError

java - c3p0 导致应用程序偶尔超时

javax.activation.DataSource大小问题

ios - 如何在 View Controller 之外设置数据源和委托(delegate)

reporting-services - SSRS 2012 : report builder and connection string to shared dataset