尽管使用 c3p0,但仍存在“无法打开连接”问题

`Could not open connection` issue despite using c3p0

几个月来,我一直在 Spring 引导应用程序中使用 c3p0 进行连接池。一切都很好,直到大约 2 周前我开始遇到连接问题,尤其是在早上。每天早上,当我尝试登录我的应用程序时,它都会抛出 Could not open connection 错误。然后我会重新启动我的应用程序以消除问题。我无法找出问题的根本原因。

这是我的 hibernate.cfg.xml:

hibernate-configuration>
<session-factory>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mydb?autoReconnect=true</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">abc123</property>
    <property name="hibernate.dialect">config.CustomDialect</property>

    <property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
    <property name="hibernate.c3p0.initialPoolSize">5</property>
    <property name="hibernate.c3p0.minPoolSize">5</property>
    <property name="hibernate.c3p0.maxPoolSize">100</property>
    <property name="hibernate.c3p0.checkoutTimeout">3000</property>
    <property name="hibernate.c3p0.maxStatementsPerConnection">30</property>
    <property name="hibernate.c3p0.unreturnedConnectionTimeout">3000</property>
    <property name="hibernate.c3p0.debugUnreturnedConnectionStackTraces">true</property>

    <property name="show_sql">true</property>
    <property name="format_sql">true</property>
    <property name="hbm2ddl.auto">update</property>

...
POJO mappings
</session-factory>
</hibernate-configuration>

这是我的 HibernateUtil Class:

public class HibernateUtil {

private static final SessionFactory sessionFactory;
static {
    try {
        Configuration configuration = new Configuration().configure();
        StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
                .applySettings(configuration.getProperties());
        sessionFactory = configuration.buildSessionFactory(builder.build());

    } catch (Exception ex) {
        throw new ExceptionInInitializerError(ex);
    }
}

public Session openSession() {
    return sessionFactory.openSession();
}
}

我已将 c3p0 调试配置添加到我的应用程序以剔除未返回的连接(以防内存泄漏)并为其生成堆栈跟踪,但日志中没有显示任何内容。

这是今天早上的一些日志:

https://pastebin.com/MGb4Miau

谁能帮我看看问题出在哪里?

编辑CustomDialect Class:

public class CustomDialect extends MySQL5InnoDBDialect {
public String getTableTypeString() {
    return " ENGINE=InnoDB DEFAULT CHARSET=utf8";
    }
}

出现此问题是因为您 运行 数据库连接不足。

  1. 保持连接的查询太慢。
  2. 您有很多连接需求无法满足最大池大小 100,这是预期的原因,因为问题是在 运行 一天后出现的。
  3. 或者你有源泄漏,因为你没有在 ether t运行saction 成功或失败后关闭连接。

From C3P0 logs on debug try to see how many connections are requested.

还有

理想情况下,你不能在生产中使用 unreturnedConnectionTimeout,所以你必须调试连接泄漏,当你没有更多的泄漏时删除 unreturnedConnectionTimeoutdebugUnreturnedConnectionStackTraces 配置。


编辑

试试这些配置:

<property key="hibernate.connection.characterEncoding">UTF-8</property>
<property key="hibernate.connection.useUnicode">true</property>

因为有时 Hibernate 中的编码与 MySQL db 中的编码不同。

我终于想出了解决问题的方法。我对 hibernate.cfg.xml 进行了以下更改:

 <property name="hibernate.c3p0.maxIdleTime">10800</property>
 <property name="hibernate.c3p0.maxIdleTimeExcessConnections">600</property>

而且有效! maxIdleTime 属性 从池中删除空闲时间超过指定时间段(以秒为单位)的连接,这确保我的连接不时刷新并且 maxIdleTimeExcessConnections让我从池中剔除超过 minPoolSize 的空闲时间超过指定时间段(以秒为单位)的连接。这样我就可以确保池中的连接不会太多,而且它们都是新鲜的。