paulk-asert opened a new pull request, #2895: URL: https://github.com/apache/groovy/pull/2895
The prepared-statement cache was an unbounded HashMap keyed on the SQL text, mutated from getAbstractStatement without synchronization. Two problems followed. It grew without limit whenever the text varied rather than the parameters — an inList expands to a different placeholder count per list size, so a caller sizing the list mints a distinct cached statement each time, held open until the Sql is closed. And a shared Sql using the cache from more than one thread could corrupt the map. The cache is now a synchronized, access-ordered LinkedHashMap that evicts the least recently used statement past a cap, closing it as it goes so a bounded cache does not leak the cursor it drops. The cap is statementCacheSize, default 256, settable and overridable with the groovy.sql.statement.cache.size system property; 0 or less keeps the old unbounded behaviour for anyone who relied on it. Statement creation stays outside the lock — only the get-then-put is synchronized — so preparing a statement does not serialize other callers, and a create race keeps the first result and closes the loser rather than leaking it. One consequence to note: with a shared Sql caching across threads, a bound below the working set can now evict and close a statement another thread is about to reuse. A single Sql is typically used serially or per connection; where it is shared, size the cache above the working set (or leave it unbounded). Default 256 is generous enough that ordinary use never evicts. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
