我有一个 Spring Boot - JPA - Postgres 多租户设置,其中每个租户都在一个单独的模式中。直到今天,当我尝试创建超过 5 个租户时,一切都运行良好。不,我在启动时遇到了这个异常:
java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30003ms
我的 Hikari CP 最大大小为 5。我在 DEBUG 日志中有 Hikari,日志说:
HikariPool-1 - Pool stats (total=5, active=5, idle=0, waiting=0)
据我了解,Hikari 无法释放到不同模式的连接,所以我最终遇到了这个错误。
我的多租户连接提供商是这样的:
@Component
class MultiTenantConnectionProviderImpl(private val dataSource: DataSource) : MultiTenantConnectionProvider {
override fun getAnyConnection(): Connection {
return dataSource.connection
}
override fun releaseAnyConnection(connection: Connection) {
connection.close()
}
override fun getConnection(tenantIdentifier: String): Connection {
val connection = anyConnection
try {
connection.schema = tenantIdentifier
} catch (e: SQLException) {
throw HibernateException(
"Could not alter JDBC connection to specified schema [$tenantIdentifier]", e
)
}
return connection
}
override fun releaseConnection(tenantIdentifier: String, connection: Connection) {
try {
connection.schema = null
} catch (e: SQLException) {
throw HibernateException(
"Could not alter JDBC connection to null schema", e
)
}
connection.close()
}
override fun isUnwrappableAs(unwrapType: Class<*>): Boolean {
return false
}
override fun <T> unwrap(unwrapType: Class<T>): T? {
return null
}
override fun supportsAggressiveRelease(): Boolean {
return true
}
}
如果我将调试器设置为 on releaseConnection
,它永远不会去那里。它去了一次,releaseAnyConnection
但实际上并没有将连接从活动连接中移开。
所以现在我被困在这里,有点不知道如何继续前进。
如果我向每个租户提出了至少一个请求,则会发生此异常。问题是,当我的应用程序启动时,它会从配置模式中查询所有租户模式名称,然后针对所有这些模式(在循环中)执行 Liquibase 脚本,以确保所有租户模式都是最新的。因此,在启动后,如果我的租户数量多于连接池允许的最大连接数,我肯定会面临这种异常情况。我可以从这个应用程序中删除模式更新,但我仍然希望有数百个同时登录到我的应用程序的租户,所以迟早我仍然会遇到这个问题。通过谷歌搜索,我发现有些人遇到了这个问题,因为他们的查询运行了很长时间,但与多租户无关。
我的应用程序.yml:
spring:
jpa:
hibernate.ddl-auto: none
properties.hibernate.jdbc.lob.non_contextual_creation: true
database-platform: org.hibernate.dialect.PostgreSQL9Dialect
datasource:
jdbcUrl: jdbc:postgresql://localhost:5432/mydb
username: mydb
password: mydb
driverClassName: org.postgresql.Driver
type: com.zaxxer.hikari.HikariDataSource
maximumPoolSize: 5
Spring Boot 版本为 2.0.5.RELEASE 和 Hikari 2.7.9