0

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

Tarmo
  • 3,851
  • 2
  • 24
  • 41
  • @user7294900 Not sure what exactly interests you but I added some pieces. – Tarmo Apr 08 '19 at 11:08
  • what's your hibernate version? – Ori Marko Apr 08 '19 at 11:10
  • I figured out what the problem was. When I executed liquibase scripts, I was acquiring db connections outside of hibernate and I did not close them manually. If I do close them manually then everything is OK. – Tarmo Apr 08 '19 at 11:15

0 Answers0