Refresh cache triggered by changes in database is it possible? - spring

In my application I'm using Spring, Hibernate and EHCache. Problem is that database is being modifiy by another application.
Is it possible, is there is any implemented solution to refresh cache based on some database changes? I can use some additional column for versioning etc.
Any ideas?

What you are looking for is know as Read-Write Through Caching. EhCache supports it.
From EhCache Documentation:
Write-through caching is a caching pattern where writes to the cache
cause writes to an underlying resource. The cache acts as a facade to
the underlying resource. With this pattern, it often makes sense to
read through the cache too. Write-behind caching uses the same client
API; however, the write happens asynchronously. Ehcache-2.0 introduced
write-through and write-behind caching. While file systems or a
web-service clients can underlie the facade of a write-through cache,
the most common underlying resource is a database.
Here is a detailed article:
http://www.ehcache.org/documentation/2.8/apis/write-through-caching.html#write-through-and-write-behind-caching-with-the-cachewriter-

Ehcache does not support such a scenario out of the box. Write-through is when changes flow the other way: your application updates the cache and in the background the cache pushes the updates to the database.
In order to push database updates to your application, you will have to come up with your own solution. The ideal way is to not have two different applications hitting the same data but instead have one of the two applications go through the other, so that a single application owns this set of data.

Used below solution to refresh cache after each database save
#CacheEvict(cacheNames = {"my-cache"}, allEntries = true)
public MyObject save(MyObject object) {
MyObject myObject = myRepo.save(object);
CompletableFuture.runAsync(() -> config.loadData());
return myObject;
}

Related

Load data from Database once and available all the time using spring and show in JSP

I want to Load Dropdown data from Database at once and set inside java object and tie to my view (JSP page ) and available all the time for that particular controller or functionality using spring mvc AND jsp pages.
I dont want to load on application start up as ours is big one and and each functionality is independent.
It takes a lot of time to start the application if i load on application start up
Is there a way to it using spring mvc pattern and using JSP
Could someone please let me know how to do it
As you have not mentioned how frequently you are doing the database operation or how frequently you are fetching the data. Considering the average user.
Approach: Create your own local cache/ program cache implementation.
Instead of loading all the data from the database during startup, load only master data which will be common for all. If master data is also high then you can perform the lazy loading approach.
Load the data of a specific feature when it is requested for the first time. Keep the data in the local cache.
Whenever someone is making the changes then add the data in the cache and save the same to the database. so you will always have latest data in the cache.
Advantage:
Very useful for common or static master data
-If you need good business logic for some common data. This way only once you are processing the data and keeping cache.
-Fetching the data is very fast as it doesn't involve database request except for the first time
Disadvantage:
If you have a very high number of users and a very high update operation then the updating cache will delay the update process as you need to update it sequentially.
I suggest you can use a combination of approaches to improve the code quality and processing.
This sounds like a typical cache functionality.
Spring supports caching out of the box by #EnableCaching on application level and #Cacheable(“cachename”) on the repository method retrieving your dropdown data. In your simple use case you not even need an additional framework as there is a CacheManager based on ConcurrentHashMap which simply caches for ever.
With caching in place your controller can simply fetch the dropdown data from the repository. Caching will ensure only the first call will really fetch from database and keeps the result in memory for all upcoming calls.
If you ever need more sophisticated caching you only have to exchange the cache manager and configure the cache for your needs.

Handling dictionary values stored in DB - Spring

I am developing some SPA with a backend written in Java (Spring Boot). In relational DB that backend connects to, there is a table with some dictionary values. Values can edited by users of the app, but it's done really, really rarely (almost never).
Those dictionary values are used in a lot of pages on UI and because of that I would like to "cache" them in a way. What I want to achieve is that I want to load dictionary values on startup to avoid asking DB for values during every request between UI and Backend.
Firstly, I thought about just loading it on the UI part of the app, when user enters the page for the first time. Then I ruled it out, since when one of the users changes the values, it should be reloaded.
What I think might work is just loading them on startup of Backend into some collection (that can be safely used in concurent environment, probably ConcurrentMap) and then during some GET requests asking that collection for the values (instead of DB). When the values are changed, that request just updates the DB table and reloads them into collection.
Then I thought that the collection solution won't be enough, when my backend would be scaled up to more than one instance. In that case, only one of instances will be updated and the second one will provide outdated data. We can avoid it and force refreshes i.e. every 15 minutes (instead of on demand during values update).
But what I think is the best solution is to start some redis service on a side, load dictionary values into it and after every DB update of the values just update the redis instance with the new ones. Every instance of backend would use the same instance of redis, which seems quicker than executing query (select * from _ where _ = _) on DB.
What do you think? Is my thought process is correct? Do you have any ideas that can help solve my issue?
If you are using Spring you could check out Spring Cache Abstraction. That way your cache will be up-to-date whenever some change occurs.
Out of the box few implementations are supported by Spring:
Spring provides a few implementations of that abstraction: JDK java.util.concurrent.ConcurrentMap based caches, Ehcache 2.x, Gemfire cache, Caffeine, and JSR-107 compliant caches (such as Ehcache 3.x). See Plugging-in Different Back-end Caches for more information on plugging in other cache stores and providers.
If you decide to use Memcached implementation you can check out this library (uses Xmemcached under the hood) here.
You could also check a small demo app of how to use Spring Cache Abstraction in your project (link).
I think your in the right path with your approach in terms of 'caching'. I suggest you also check Memcached for it simplicity. Redis is a good choice but still it depends on your requirements and if you need that much feature. just my 2cent
https://aws.amazon.com/elasticache/redis-vs-memcached/
https://devcenter.heroku.com/articles/spring-boot-memcache#add-caching-to-spring-boot
Thanks,

Asp.net core Caching In-Memory and Distributed together

Can In-Memory caching and Distributed Cache be used together in the same application? Does it make sense after all?
A logic scenario that comes to my mind is to manager Session state (on top of In-Memory, taking advantage of sticky sessions ) and Distributed for other caching. However I don't know if this makes sense after all.
Yes, you can. One implements IMemoryCache, other implements IDistributedCache.
IMemoryCache will not work properly if you have non-sticky sessions and multiple servers.
Also you may want to use service.AddDistributedMemoryCache(); instead of service.AddMemoryCache();

Caching all entities in Cache Layer and Synchronizing with Database

Is it possible, reliable and secure to cache all entities in distrubuted cache and notifies dao layer on update? My possible idea is;
Use JPA 2.1 and Hibernate implementation.
On creation persist it db
After persisting it, cache it to distrubuted cache.
Canalise all read actions to cache
on update notify dao layer to update entity .
yes you can design a system that will
On addition: persists data to db and adds to cache
On read: reads data from cache, and considers a cache miss as not
present in database as well.
On update: updates data in db and then updates in cache (or vice
versa)
On delete: deletes data from cache and then deletes from database
This approach will work fine if you have a single application using that database and if data is not that critical. However if data integrity is of more importance, you may face following problems in this approach:
You may face a cache miss when data is present in database(persisted
but not yet cached)
You may get stale data from cache (updated in db but not yet updated
in cache)
Also if data is removed from database by some other application, it
will still ramained cached in distributed cache(invalid data on
reads)
A better mothod my be if you use a rich featured distributed caching solution like NCache / Tayzgrid which provides Read Trough / Write behind features. This way your application will only need to use cache for all reads, writes or updates and cache will keep database updated using configured providers.
Another approach may be to use distributed cache as hibernate's second level cache and you will not need to add a caching layer by your self. See this article for details about hibernate's second level cache.
Distributed caching solutions like Tayzgrid provide caching provider for hibernate that can be easily configured. You can find hibernate providers for other solutions as well.

Best way to cache persistent data (e.g. code books) in Spring?

I have a series of code books in my database, and I am using plain JDBC calls to fetch them and store them in a collection. I would like to put these in some kind of a cache at application startup time in order to save time later.
I don't need any fancy stuff like automatic object invalidation, TTL etc - the code books change rarely, so I'll trigger the update myself and just reload the whole cache when the need arises.
The project where I need this uses Spring, and this is my first project using it. Is there a standard/elegant way to do this in Spring?
Thanks.
Check out Spring-cache.
Supports EHCache, OSCache and a memory cache, but allows pluggable cache providers too.

Resources