尽管使用 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 调试配置添加到我的应用程序以剔除未返回的连接(以防内存泄漏)并为其生成堆栈跟踪,但日志中没有显示任何内容。
这是今天早上的一些日志:
谁能帮我看看问题出在哪里?
编辑:CustomDialect
Class:
public class CustomDialect extends MySQL5InnoDBDialect {
public String getTableTypeString() {
return " ENGINE=InnoDB DEFAULT CHARSET=utf8";
}
}
出现此问题是因为您 运行 数据库连接不足。
- 保持连接的查询太慢。
- 您有很多连接需求无法满足最大池大小
100
,这是预期的原因,因为问题是在 运行 一天后出现的。
- 或者你有源泄漏,因为你没有在 ether t运行saction 成功或失败后关闭连接。
From C3P0 logs on debug try to see how many connections are requested.
还有
理想情况下,你不能在生产中使用 unreturnedConnectionTimeout
,所以你必须调试连接泄漏,当你没有更多的泄漏时删除
unreturnedConnectionTimeout
和 debugUnreturnedConnectionStackTraces
配置。
编辑
试试这些配置:
<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
的空闲时间超过指定时间段(以秒为单位)的连接。这样我就可以确保池中的连接不会太多,而且它们都是新鲜的。
几个月来,我一直在 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 调试配置添加到我的应用程序以剔除未返回的连接(以防内存泄漏)并为其生成堆栈跟踪,但日志中没有显示任何内容。
这是今天早上的一些日志:
谁能帮我看看问题出在哪里?
编辑:CustomDialect
Class:
public class CustomDialect extends MySQL5InnoDBDialect {
public String getTableTypeString() {
return " ENGINE=InnoDB DEFAULT CHARSET=utf8";
}
}
出现此问题是因为您 运行 数据库连接不足。
- 保持连接的查询太慢。
- 您有很多连接需求无法满足最大池大小
100
,这是预期的原因,因为问题是在 运行 一天后出现的。 - 或者你有源泄漏,因为你没有在 ether t运行saction 成功或失败后关闭连接。
From C3P0 logs on debug try to see how many connections are requested.
还有
理想情况下,你不能在生产中使用 unreturnedConnectionTimeout
,所以你必须调试连接泄漏,当你没有更多的泄漏时删除
unreturnedConnectionTimeout
和 debugUnreturnedConnectionStackTraces
配置。
编辑
试试这些配置:
<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
的空闲时间超过指定时间段(以秒为单位)的连接。这样我就可以确保池中的连接不会太多,而且它们都是新鲜的。