我正在使用hibenate和spring并且在我们从具有250个用户的jmeter命中时获得以下异常
“引起:com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:数据源拒绝建立连接,来自服务器的消息:”连接太多“
hibernate_cfg.xml
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/my_db</property>
<property name="hibernate.connection.username">user1</property>
<property name="hibernate.connection.pool_size">1</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">50</property>
<property name="hibernate.c3p0.timeout">300</property>
<property name="hibernate.c3p0.max_statements">500</property>
<property name="hibernate.c3p0.idle_test_period">3000</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.hbm2ddl.auto">update</property>`
春天
<bean id="dataSource" scope="prototype" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>${dbDriver}</value>
</property>
<property name="url">
<value>${dbURL}</value>
</property>
<property name="username">
<value>${dbUsername}</value>
</property>
<property name="password">
<value>${dbPassword}</value>
</property>
</bean>
答案 0 :(得分:5)
这是来自服务器的消息,因此,我将检查服务器报告的已连接客户端的数量。如果这是一个预期的数字,比如500左右,那么我会在服务器上增加这个限制,如果你真的希望你的应用程序的并发级别。否则,减少客户端数量。
关于它是如何工作的一些背景知识:每个客户端都是服务器上的一个线程,每个线程至少会消耗一个连接。如果你做得对,一旦线程完成,连接将返回池(即:一旦响应被发送到客户端)。因此,在最好的情况下,如果您连接了大约500个用户,则您将拥有500个连接。如果看到的数字接近并发用户数的倍数(即:2个用户,4个连接),则每个线程可能会消耗多个连接(这是您为不使用由提供的数据源而支付的价格您的应用程序服务器,如果您正在使用它)。如果您看到一个非常高的数字(例如,用户数量的10倍),那么您可能会在某处发生连接泄漏。如果您忘记关闭连接,可能会发生这种情况。
我真的建议使用由您的应用程序服务器管理的EntityManager,并使用它提供的DataSource。然后,您不必担心管理连接池。
答案 1 :(得分:4)
我认为您的问题是您的数据源没有连接池。 来自org.springframework.jdbc.datasource.DriverManagerDataSource javadocs:
注意:此类不是实际的连接池;实际上并没有 *泳池连接。
在该类的javadocs中也可以使用Apache的Jakarta Commons DBCP,以防你需要连接池。
如果您需要J2EE容器外的“真实”连接池, 考虑Apache's Jakarta Commons DBCP或C3P0。 Commons DBCP BasicDataSource和C3P0的ComboPooledDataSource是完全连接 pool bean,支持与此类相同的基本属性 特定设置(例如最小/最大池大小等)。
我使用它,它就像一个魅力:)
希望我帮忙。
答案 2 :(得分:1)
如果每次创建连接都可能导致此问题。解决方案很简单。单身。每个sessin的连接。所以我在帖子的底部发布了一些代码。检查错误和正确的编码。 1-不正确,2-正确
private EntityManagerFactory emf = null;
@SuppressWarnings("unchecked")
public BaseDAO() {
emf = Persistence.createEntityManagerFactory("aaHIBERNATE");
persistentClass = (Class<T>) ((ParameterizedType) getClass()
.getGenericSuperclass()).getActualTypeArguments()[0];
}
private static EntityManagerFactory emf = null;
@SuppressWarnings("unchecked")
public BaseDAO() {
if (emf == null) {
emf = Persistence.createEntityManagerFactory("aaHIBERNATE");}
persistentClass = (Class<T>) ((ParameterizedType) getClass()
.getGenericSuperclass()).getActualTypeArguments()[0];
}
答案 3 :(得分:0)
您需要在应用程序和数据库服务器中跟踪它。
您需要增加数据库服务器设置中的最大打开连接值。
要更改最大开放连接,您需要在数据库服务器下的my.cnf文件中修改max_connections
和max_user_connections
。
您还可以为每个用户授予/编辑最大连接数。 more info available here