TestContainers SQL 连接异常过多
TestContainers SQL too many connections exception
我正在使用 Spring 引导并定义了 3 SQL 个数据源。
我正在使用 SpringBoot 属性为数据源制作 3 个 TestContainer。
当我 运行 我的测试时,容器越来越慢,最终我终于得到了一个
Caused by: java.sql.SQLNonTransientConnectionException: Too many connections
异常。
示例测试是:
@Test
@DisplayName("Require Client Access.")
@Transactional(transactionManager = "thirdTransactionManager")
@Sql(
scripts = "/db/sql/some_test_data_basic.sql",
config = @SqlConfig(dataSource = "thirdDatasource", transactionManager = "thirdTransactionManager"))
void requireCustomerAccess() throws CompClientAccessException {
//Assertions
}
我正在使用 FlyWay 迁移架构,所以我不确定在每次测试之间 class Hikari 或 Flyway 是否在每个方法 class 导致连接过多后没有关闭其连接池连接?
我有 3 个 TestContainer 通过 Spring 的道具启动,如下所示。我可以在 docker.
中看到它们
datasource.jdbc.url=jdbc:tc:mysql:8.0.22:///databasename?TC_TEMPFS=/testtempfs:rw
datasource.username=dev
datasource.password=password
DatasourceConf 的片段(三个之一):
@Qualifier("thirdDatasource")
@Bean(name = "thirdDatasource")
public HikariDataSource thirdDatasource() {
HikariDataSource hikariDataSource = new HikariDataSource();
hikariDataSource.setMaximumPoolSize(3);
hikariDataSource.setJdbcUrl(thirdUrl);
hikariDataSource.setUsername(thirdUsername);
hikariDataSource.setPassword(thirdUsername);
hikariDataSource.setDriverClassName(driverClassName);
return hikariDataSource;
}
@Bean(name="thirdTransactionManager")
@Qualifier("thirdTransactionManager")
public PlatformTransactionManager thirdTransactionManager(
final @Qualifier("thirdEntityManagerFactory") LocalContainerEntityManagerFactoryBean thirdEntityManagerFactory) {
return new JpaTransactionManager(thirdEntityManagerFactory.getObject());
}
我猜 HikariPools 正在为每个测试重新制作 class 而不是关闭?
o.h.e.j.s.SqlExceptionHelper : HikariPool-45 - Connection is not available, request timed out after 30000ms.
感谢您的帮助。
感谢 M. Deinum 的帮助:
在测试之间缓存应用程序上下文以帮助加速测试:
https://docs.spring.io/spring-framework/docs/current/reference/html/testing.html#testcontext-ctx-management-caching
创建了一个新的上下文,例如使用了一组不同的 @MockBean
,使用了不同的 Profiles
。
因此,在我的测试环境中缓存了超过 16 个 Hikari 数据源,它们都至少使用了 3-10 个连接。这超过了 TestContainer 的默认值,因此当具有不同上下文的一定数量的测试已经 reached/cached 时,连接池(作为 的总和)将无法创建到数据源的新连接( s) 给出 SQL 连接错误。
外卖:
多考虑测试重叠。 IE。如果某些逻辑已经完成,是否需要完整的 @SpringBootTest
,或者 MocMvc
或 DataJPATest
就足够了。
缓存上下文的数量默认为 32,但可以通过 JVM 系统参数设置(参见文档)。
您还可以通过在测试资源目录中添加一个包含以下内容的 spring.properties
文件来减少缓存的最大大小:
spring.test.context.cache.maxSize=4
在这种情况下,最大缓存大小将为 4,而不是文档中提到的默认值 32。
如果您遇到此问题,很可能意味着缓存首先不适合您,因为许多应用程序上下文被认为是唯一的。所以,缩小尺寸似乎是权宜之计。
我正在使用 Spring 引导并定义了 3 SQL 个数据源。 我正在使用 SpringBoot 属性为数据源制作 3 个 TestContainer。
当我 运行 我的测试时,容器越来越慢,最终我终于得到了一个
Caused by: java.sql.SQLNonTransientConnectionException: Too many connections
异常。
示例测试是:
@Test
@DisplayName("Require Client Access.")
@Transactional(transactionManager = "thirdTransactionManager")
@Sql(
scripts = "/db/sql/some_test_data_basic.sql",
config = @SqlConfig(dataSource = "thirdDatasource", transactionManager = "thirdTransactionManager"))
void requireCustomerAccess() throws CompClientAccessException {
//Assertions
}
我正在使用 FlyWay 迁移架构,所以我不确定在每次测试之间 class Hikari 或 Flyway 是否在每个方法 class 导致连接过多后没有关闭其连接池连接?
我有 3 个 TestContainer 通过 Spring 的道具启动,如下所示。我可以在 docker.
中看到它们datasource.jdbc.url=jdbc:tc:mysql:8.0.22:///databasename?TC_TEMPFS=/testtempfs:rw
datasource.username=dev
datasource.password=password
DatasourceConf 的片段(三个之一):
@Qualifier("thirdDatasource")
@Bean(name = "thirdDatasource")
public HikariDataSource thirdDatasource() {
HikariDataSource hikariDataSource = new HikariDataSource();
hikariDataSource.setMaximumPoolSize(3);
hikariDataSource.setJdbcUrl(thirdUrl);
hikariDataSource.setUsername(thirdUsername);
hikariDataSource.setPassword(thirdUsername);
hikariDataSource.setDriverClassName(driverClassName);
return hikariDataSource;
}
@Bean(name="thirdTransactionManager")
@Qualifier("thirdTransactionManager")
public PlatformTransactionManager thirdTransactionManager(
final @Qualifier("thirdEntityManagerFactory") LocalContainerEntityManagerFactoryBean thirdEntityManagerFactory) {
return new JpaTransactionManager(thirdEntityManagerFactory.getObject());
}
我猜 HikariPools 正在为每个测试重新制作 class 而不是关闭?
o.h.e.j.s.SqlExceptionHelper : HikariPool-45 - Connection is not available, request timed out after 30000ms.
感谢您的帮助。
感谢 M. Deinum 的帮助:
在测试之间缓存应用程序上下文以帮助加速测试: https://docs.spring.io/spring-framework/docs/current/reference/html/testing.html#testcontext-ctx-management-caching
创建了一个新的上下文,例如使用了一组不同的 @MockBean
,使用了不同的 Profiles
。
因此,在我的测试环境中缓存了超过 16 个 Hikari 数据源,它们都至少使用了 3-10 个连接。这超过了 TestContainer 的默认值,因此当具有不同上下文的一定数量的测试已经 reached/cached 时,连接池(作为 的总和)将无法创建到数据源的新连接( s) 给出 SQL 连接错误。
外卖:
多考虑测试重叠。 IE。如果某些逻辑已经完成,是否需要完整的 @SpringBootTest
,或者 MocMvc
或 DataJPATest
就足够了。
缓存上下文的数量默认为 32,但可以通过 JVM 系统参数设置(参见文档)。
您还可以通过在测试资源目录中添加一个包含以下内容的 spring.properties
文件来减少缓存的最大大小:
spring.test.context.cache.maxSize=4
在这种情况下,最大缓存大小将为 4,而不是文档中提到的默认值 32。
如果您遇到此问题,很可能意味着缓存首先不适合您,因为许多应用程序上下文被认为是唯一的。所以,缩小尺寸似乎是权宜之计。