Repository navigation
FINERACT-2968: Transaction-bound cache clearing and load global configs once per transaction - #6493
Open
alberto-art3ch wants to merge 1 commit into
Open
alberto-art3ch wants to merge 1 commit into
alberto-art3ch wants to merge 1 commit into
Conversation
alberto-art3ch
marked this pull request as ready for review
September 23, 2026 03:07
alberto-art3ch
force-pushed
the
FINERACT-2684/config-cache-round-trips
branch
from
September 23, 2026 04:32
609f50d to
dfcb6ae
Compare
galovics
requested changes
Oct 19, 2026
galovics
left a comment
Contributor
There was a problem hiding this comment.
Hi @alberto-art3ch, thanks for the PR. The per-thread store and forwarding the hooks only to the active manager are a nice fix. I'd like these addressed first:
DatatableWriteServiceImpl(updateDatatablecatch): why is a swallowed DDL failure now a mapped error with a new code? That is a behaviour change with no test, and the description says "No client-visible behaviour change". Separate PR please.jersey-micrometerindependencies.gradle: unrelated to config caching and a new dependency deserves its own review. Same, please split out.removeFromCachenow evicts only<tenant>::all.ConfigurationDomainServiceJpa.getGlobalConfigurationPropertyDatais still@Cacheable("configByName")keyedtenant + name, and the old@CacheEvicthere used to clear it. Where is it evicted now? In SINGLE_NODE it looks stale until the TTL. How do the two caches interact, and is the new one redundant for the hottest caller? ThepropertyNameargument is now only a log line, drop it.- The read path returns
eclipselink.read-onlyentities shared across threads for the whole TTL, and nothing stops a later caller from calling a setter. ReturntoData(), or add a test that fails if someone does. ThreadLocalContextUtilin core now depends on the cache package. Isreset()guaranteed at the end of every request and job thread, otherwise the map leaks?- Tests run on one thread while the claim is per-thread isolation: pls add a test that thread B's
afterBegindoes not clear thread A, one thatreset()drops the store, and one integration test that switches to SINGLE_NODE viaPUT /cachesand stays cached. - Smaller:
TransactionScopedCacheManagerhas a single implementation andRuntimeDelegatingCacheManagerdoes aninstanceofanyway,CONFIG_BY_NAME_CACHE_NAMEis an alias of a constant in the wrapper, mockGlobalConfigurationPropertyis avoidable.
alberto-art3ch
force-pushed
the
FINERACT-2684/config-cache-round-trips
branch
from
October 19, 2026 22:06
dfcb6ae to
61f9034
Compare
Contributor
Author
Thanks @galovics, all addressed:
|
alberto-art3ch
force-pushed
the
FINERACT-2684/config-cache-round-trips
branch
from
October 19, 2026 22:14
61f9034 to
2d1913d
Compare
…gs once per transaction
alberto-art3ch
force-pushed
the
FINERACT-2684/config-cache-round-trips
branch
from
October 20, 2026 21:53
2d1913d to
2ee1139
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Global configuration lookups (
c_configurationby name) run on almost every request: ~17 single-row queries perwrite request under load, the most executed statement of the platform. The
configByNamecache never hits: thedefault
TransactionBoundCacheManagerclears a shared Ehcache instance on every transaction of every thread, and it keeps doing so even after switching to SINGLE_NODE viaPUT /caches.Changes, keeping the guarantee that every transaction starts from the database:
ThreadLocalCacheStore) and cleared only by that thread's transaction boundaries and byThreadLocalContextUtil.reset()(request/job end); no cross-thread clearing or locking.TransactionBoundCacheManagermoves tofineract-corenext toRuntimeDelegatingCacheManager.RuntimeDelegatingCacheManagerforwards transaction hooks only while the transaction-bound manager is active, so the SINGLE_NODE cache is no longer wiped.GlobalConfigurationRepositoryWrapperloads the whole table (76 rows) once per cache lifetime with a read-onlyquery, keyed
<tenant>::all, and evicts it on writes. Read callers get a freshGlobalConfigurationPropertyDataper call, so the cached entities can never be modified; the single mutating caller uses a dedicated for-update
lookup.
removeFromCache()no longer takes a property name (the whole snapshot is evicted).CacheConfigregisters the transaction-bound caches in Ehcache explicitly. Ehcache caches were created only fornames found by the
@Cacheablescan, so without this SINGLE_NODE would have noconfigByNamecache once the annotation is replaced by programmatic access.Note:
ConfigurationDomainServiceJpahas had no@Cacheablesince FINERACT-1724 (e9e31a8); it delegates to the wrapper, so there is a single configuration cache.Measured on the first iteration of this PR (k6, PostgreSQL 18, 36k loans): configuration statements per write request
16.7 -> 5.8 (one 76-row round trip per transaction instead of one per property), write p95 27 -> 28 ms, read mix p95
86-105 -> 90 ms. No client-visible behaviour change.
Tests:
afterBegindoes not clear thread A),reset()drops the thread's store, once-per-transaction loading, eviction, returned data cannot alter the cache,Ehcache registration of the transaction-bound caches (fails without the
CacheConfigchange).GlobalConfigurationTestswitches to SINGLE_NODE viaPUT /caches, reads, updates and checks theupdate is visible (no stale read), then restores NO_CACHE.
Out of scope (separate PRs): the datatable DDL error mapping and the
jersey-micrometerdependency that were in the first iteration.FINERACT-2684
Checklist
Please make sure these boxes are checked before submitting your pull request - thanks!
Your assigned reviewer(s) will follow our guidelines for code reviews.