Vaadin Grid DataProvider and intermittent JDBC connection pool exhaustion
0 reputation · 23 Feb 2025, 22:44 UTC
0 reputation · 23 Feb 2025, 22:44 UTC
Vaadin Flow uses DataProvider callbacks, specifically fetchFromBackEnd, to handle lazy loading for the Grid component. These callbacks execute on the UI thread to retrieve data pages from the database based on the current view.
In environments with high concurrent user volume, the way database connections are acquired and released within these callbacks can impact the JDBC connection pool. There is uncertainty regarding the optimal way to manage transaction boundaries when moving between manual CallbackDataProvider implementations and the managed SpringDataProvider integration.
What is the expected behavior of connection release when using a custom DataProvider compared to SpringDataProvider? Which pattern best prevents connection leakage during high-concurrency page requests in Vaadin Flow?
31775 reputation · 24 Feb 2025, 01:55 UTC
In Vaadin Flow, a CallbackDataProvider obtains a JDBC connection at the start of fetchFromBackEnd and keeps it open until the method returns. If the method contains blocking or long‑running work, the connection stays checked out, increasing the chance of exhausting the pool under concurrent Grid requests.
By contrast, a SpringDataProvider delegates to Spring’s @Transactional infrastructure. The transaction begins when the DataProvider calls the repository, and the transaction manager automatically closes the JDBC connection as soon as the repository method completes, even if the Grid callback itself takes longer.
Connection, Statement, and ResultSet objects.leakDetectionThreshold to surface unclosed connections.Because the UI thread in Vaadin synchronizes Grid updates, developers sometimes perform additional business logic inside fetchFromBackEnd. In a custom provider, this logic may inadvertently keep the JDBC connection open. SpringDataProvider’s automatic transaction demarcation reduces this risk, but only if the repository method remains lightweight and does not spawn additional threads that outlive the transaction.
CallbackDataProvider, wrap database access in try-with-resources blocks:
try (Connection conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
try (ResultSet rs = ps.executeQuery()) {
// build items
}
}
spring.datasource.hikari.leakDetectionThreshold=30000 // 30 seconds
maximumPoolSize to 250 to allow headroom.activeConnections, idleConnections) during load tests. If activeConnections approaches maximumPoolSize, increase the pool or reduce query latency.What is the current maximumPoolSize configured in your JDBC pool? If it is already close to the number of concurrent UI threads, even a well‑behaved SpringDataProvider may experience exhaustion.
For most Vaadin applications, using SpringDataProvider with Spring’s transaction management is the safest approach to prevent JDBC connection leaks under high concurrency. When a custom provider is unavoidable, enforce strict resource cleanup and keep the callback focused solely on data retrieval.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.