If I run all my JUnit test cases at once (~300) I get the following Exception:
如果我一次运行所有的JUnit测试用例(~300),我就会得到以下的异常:
org.postgresql.util.PSQLException: FATAL: sorry, too many clients already
at org.postgresql.core.v3.ConnectionFactoryImpl.doAuthentication(ConnectionFactoryImpl.java:293)
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:108)
at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:66)
at org.postgresql.jdbc2.AbstractJdbc2Connection.<init>(AbstractJdbc2Connection.java:125)
at org.postgresql.jdbc3.AbstractJdbc3Connection.<init>(AbstractJdbc3Connection.java:30)
at org.postgresql.jdbc3g.AbstractJdbc3gConnection.<init>(AbstractJdbc3gConnection.java:22)
at org.postgresql.jdbc4.AbstractJdbc4Connection.<init>(AbstractJdbc4Connection.java:32)
at org.postgresql.jdbc4.Jdbc4Connection.<init>(Jdbc4Connection.java:24)
at org.postgresql.Driver.makeConnection(Driver.java:393)
at org.postgresql.Driver.connect(Driver.java:267)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at test.testingTools.DatabaseConnector.getTestConnection(DatabaseConnector.java:24)
at test.repository.cascade.merge_persist.ParentCascadeMPTest.setUp(ParentCascadeMPTest.java:56)
at sun.reflect.GeneratedMethodAccessor73.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:233)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:87)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:176)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
In the postgres config (/etc/postgresql/9.2/main/postgresql.conf) the value is set to 100 as shown: max_connections = 100
在postgres配置(/etc/postgresql/9.2/main/postgresql.conf)中,该值设置为100,如下所示:max_connections = 100。
The Spring AppContext:
春天AppContext:
package test;
import java.beans.PropertyVetoException;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import org.hibernate.dialect.PostgreSQL9Dialect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableLoadTimeWeaving;
import org.springframework.context.annotation.EnableLoadTimeWeaving.AspectJWeaving;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.aspectj.EnableSpringConfigured;
import org.springframework.core.env.Environment;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import com.mchange.v2.c3p0.AbstractComboPooledDataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
@Configuration
@EnableSpringConfigured
@EnableLoadTimeWeaving(aspectjWeaving = AspectJWeaving.ENABLED)
@ComponentScan(basePackages = { "test" })
@PropertySource("META-INF/spring/props.properties")
@EnableJpaRepositories("test.repository")
public class AppContext {
@Autowired
private Environment env;
@Autowired
private DataSource dataSource;
@Bean(name = "dataSource", destroyMethod = "close")
@Profile("test")
public DataSource dataSourceTest() throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(env.getProperty("testDb.driverClass"));
dataSource.setJdbcUrl(env.getProperty("testDb.jdbcUrl"));
dataSource.setUser(env.getProperty("testDb.user"));
dataSource.setPassword(env.getProperty("testDb.password"));
setDataSourceProperties(dataSource);
return dataSource;
}
// use this to configure c3p0
/*
* with the @Repeat annotation from springframework.test at a test connecting to the test database, a PSQLException
* for too many clients can easily be reproduced to try out new configuration parameters
*/
private void setDataSourceProperties(AbstractComboPooledDataSource dataSource) {
dataSource.setAcquireIncrement(5);
dataSource.setMinPoolSize(5);
dataSource.setMaxPoolSize(100);
}
@Bean
public Map<String, Object> jpaProperties() {
Map<String, Object> props = new HashMap<String, Object>();
props.put("hibernate.dialect", PostgreSQL9Dialect.class.getName());
return props;
}
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
hibernateJpaVendorAdapter.setShowSql(false);
hibernateJpaVendorAdapter.setGenerateDdl(true);
hibernateJpaVendorAdapter.setDatabase(Database.POSTGRESQL);
return hibernateJpaVendorAdapter;
}
@Bean
public PlatformTransactionManager transactionManager() {
return new JpaTransactionManager(entityManagerFactory().getObject());
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
emf.setDataSource(this.dataSource);
emf.setJpaPropertyMap(this.jpaProperties());
emf.setJpaVendorAdapter(this.jpaVendorAdapter());
emf.setPackagesToScan("test");
return emf;
}
}
The DBUnit Database Connection:
DBUnit数据库连接:
package test;
import java.sql.Connection;
import java.sql.DriverManager;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.IDatabaseConnection;
import org.springframework.stereotype.Component;
@Component
public class DatabaseConnector {
public DatabaseConnector() {
}
public IDatabaseConnection getTestConnection() throws Exception {
Connection dbConnection = null;
Class.forName("org.postgresql.Driver");
dbConnection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/test", "user", "password");
IDatabaseConnection connection = new DatabaseConnection(dbConnection);
return connection;
}
}
Thinks I tried:
认为我尝试:
-
Change the setMaxPoolSize for c3p0 (from 1 to 100)
更改c3p0的setMaxPoolSize(从1到100)
-
Increase max_connections in the postgres config (postgres didn't start up anymore)
在postgres配置中增加max_connections (postgres不再启动)
-
Add Thread.sleep(1000); to @Before and @Before (1 to 10 Seconds)
添加thread . sleep(1000);@Before和@Before(1 - 10秒)
If I run all the test often enough some times it will work, also when I only run a subset it works most of the time.
如果我经常运行所有的测试,有时它会起作用,而且当我只运行一个子集时,它大部分时间都在运行。
I'm also convinced that 100 database connections should be enough for 300 tests...
我还确信,100个数据库连接应该足够300个测试……
1 个解决方案
#1
0
I found the Problem in the DBUnit Database Connection. It created a new Connection all the time.
我在DBUnit数据库连接中发现了这个问题。它一直在创造一种新的联系。
Now it behaves like a Singleton and the problem is gone.
现在它就像一个单例,问题已经解决了。
package test.testingTools;
import java.sql.Connection;
import java.sql.DriverManager;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.IDatabaseConnection;
import org.springframework.stereotype.Component;
@Component
public class DatabaseConnector {
IDatabaseConnection connection;
public DatabaseConnector() throws Exception {
Connection dbConnection = null;
Class.forName("org.postgresql.Driver");
dbConnection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/test", "user", "password");
connection = new DatabaseConnection(dbConnection);
}
public IDatabaseConnection getTestConnection() {
return connection;
}
}
#1
0
I found the Problem in the DBUnit Database Connection. It created a new Connection all the time.
我在DBUnit数据库连接中发现了这个问题。它一直在创造一种新的联系。
Now it behaves like a Singleton and the problem is gone.
现在它就像一个单例,问题已经解决了。
package test.testingTools;
import java.sql.Connection;
import java.sql.DriverManager;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.IDatabaseConnection;
import org.springframework.stereotype.Component;
@Component
public class DatabaseConnector {
IDatabaseConnection connection;
public DatabaseConnector() throws Exception {
Connection dbConnection = null;
Class.forName("org.postgresql.Driver");
dbConnection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/test", "user", "password");
connection = new DatabaseConnection(dbConnection);
}
public IDatabaseConnection getTestConnection() {
return connection;
}
}