I have a Spring Boot - JPA - Postgres multi tenancy setup where every tenant is in a separate schema. Everything was working fine until today when I tried to create more than 5 tenants. No I'm getting this exception on startup:
java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30003ms
My Hikari CP max size is 5. I have Hikari on DEBUG log and logs say:
HikariPool-1 - Pool stats (total=5, active=5, idle=0, waiting=0)
As I understand Hikari is not able to release connections to different schemas and so I end up with this error.
My multi tenancy connection provider is like this:
@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
}
}
If I set my debugger on releaseConnection
, it never goes there. It goes once to releaseAnyConnection
but that actually does not move connection away from active connections.
So now I'm stuck here and a bit out of ideas how to move forward to this.
This exception happens if I have made at least one request with each tenant. Problem is that when my application starts up, it queries all tenant schema names from configuration schema and then executes Liquibase scripts against all those schemas (in a loop) to make sure all tenant schemas are up to date. So after startup I am guaranteed to be in a situation facing this exception if I have more tenants than connection pool has maximum allowed connections. I could remove schema updates out of this application, but still I would expect to have hundreds of simultaneous tenants logged in to my application at once, so sooner or later I would still face this problem. By googling I found some people who have had this problem because they have queries that run for very long time, but nothing related to multi tenancy.
My application.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 version is 2.0.5.RELEASE and Hikari 2.7.9