У меня есть установка для нескольких арендаторов Spring Boot - JPA - Postgres, где каждый арендатор находится в отдельной схеме. Все работало нормально до сегодняшнего дня, когда я попытался создать более 5 арендаторов. Нет, я получаю это исключение при запуске:
java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30003ms
Максимальный размер моего Hikari CP - 5. У меня есть Hikari в журнале DEBUG, и в журналах написано:
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
}
}
Если я установлю свой отладчик на releaseConnection
, он никогда не пойдет туда. Один раз он переходит к releaseAnyConnection
, но это фактически не удаляет соединение от активных соединений.
Так что теперь я застрял здесь и немного не знаю, как двигаться к этому.
Это исключение происходит, если я сделал по крайней мере один запрос с каждым арендатором. Проблема заключается в том, что когда мое приложение запускается, оно запрашивает все имена схем арендаторов из схемы конфигурации, а затем выполняет сценарии Liquibase для всех этих схем (в цикле), чтобы убедиться, что все схемы арендаторов обновлены. Таким образом, после запуска я гарантированно окажусь в ситуации, с которой столкнется это исключение, если у меня будет больше арендаторов, чем у пула соединений максимально допустимые соединения. Я мог бы удалить обновления схемы из этого приложения, но, тем не менее, я ожидал, что в мое приложение одновременно войдут сотни одновременных клиентов, поэтому рано или поздно я все равно столкнусь с этой проблемой.
Путем поиска в Google я нашел некоторых людей, у которых была эта проблема, потому что у них есть запросы, которые выполняются в течение очень долгого времени, но ничего не связано с мульти-арендой.
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 2.0.5. ВЫПУСК и Hikari 2.7.9