MyBatis caching strategy in distributed system - caching

I'd like to know how myBatis cache (local and second level) to handle data in distributed system. I have 5 instances running against Oracle db, and I use MyBatis for data access. All 5 instances are same but running on different servers. The Mybatis are configured to use SESSION cache, which being said the cache is cleared when any insert/delete/update statement is executed.
When 1 instance runs , the local cache of that server is cleared. How does the other 4 instances know the cache needs to be flushed/renewed?

If you are using the built-in cache, no they don't. Never enable secondary cache if you are using MyBatis in a distributed environment with default cache because they don't know what happens each other and won't clear the staled cache when change happens.
You need to set up an external cache service, such as Ehcache and Redis, to make MyBatis secondary cache usable.
Please refer to http://mybatis.org/ehcache-cache/ and http://mybatis.org/redis-cache/

Giving a track:
I guess all instances are behind a load balancer and running against a single Oracle DB.
Instances nodes would better be in a cluster, otherwise, how could they communicate with each other. Then cache may be shared between cluster's nodes, for example as stated in Jboss doc, working with Hibernate.
The question is more about how to configure server (or application, in files such as beans.xml) to use MyBatis cache.
If the SessionFactory is declared #ApplicationScoped, it could be enough.

Related

Infinispan cache eviction using CLI

I have a couple of entities for JBoss 7, where I set the caching as annotation like:
#Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL, region = "USERS")
and time to time I need to evict (flush) this cache region. Prior JBoss 7 (Infinispan) I used an MBean what did this flushing. But now JBoss 7 is not the case, so I need a solution based on something what can be elaborated programatically (ex. CLI)
Does anybody know how to evict manually an Infinispan local cache using CLI?
I am using JBoss 7 in standalone mode and in jboss-cli, for the eviction operation there is no way to specify the region's name.
Any hint?
SK
Infinispan doesn't have regions, you can only clear the entire cache.
On the other hand, Hibernate should create a separate Infinispan cache for each region.

Terracotta Disabling L2 cache and object serialization

I'm quite new to Terracotta and I've installed and made it work properly with EHcache for distribute caching, but what I'm getting now is not what I really want.
In my application I would like to have several client caches (L1) with ehcache, and "propagate" the invalidation of a removed key from a client to all the other clients. I don't want that my cache will reside also on the terracotta server, so I'd like to simply disable L2 caching, so that my objects don't need to be serializable (the only actions done on cache are PUT and REMOVE).
I know this could be done using simply ehcache, but i have no multicasting support in my environment (Amazon EC2) and my clients will be automatically created with autoscaling features, so I cannot know their IPs.
So basically, I need a Terracotta Server only to propagate the invalidation request to all the clients. Is there any way to accomplish this?
Thanks a lot!
When you use EhCache backed by Terracotta and in your cache configuration you specify to use terracotta, e.g.:
<cache name="com.xyz.MyPOJO"
<terracotta/>
</cache>
then your class must be serializable (since Terracotta will attempt to store it on the cache server instance.
However, in your configuration you can specify not to use Terracotta for some caches, e.g.
<cache name="com.xyz.MyPOJO"
<terracotta/>
</cache>
<cache name="com.xyz.NotServerStoredPOJO"
</cache>
Then your "NotServerStoredPOJO" from the example above will not be stored on the terracotta cache server...instead it will live only in your local EhCache... but by doing that you will not be able to propagate it to other instances if your EhCache in diff JVMs.
So, perhaps you will need to keep something on the terracotta server (some sort of flags/ids) that will indicate what to invalidate. Then in your application code have a common class/functionality that will check that flag before getting value from the local EhCache...if it finds flag/id to be deleted, then it will delete it from local cache and will not return back anything to the requester.
On on the other hand, your use case kind of defeats the purpose of having central cache server. If you want to coordinate multiple cache instances without central location, you can use JGroups http://www.jgroups.org (instead of Terracotta)...its free of commercial license also. But then you'll need to implement your own mechanism over JGroups of how to invalidate certain entries in your local EhCache instances...

replicated ehcache on Glassfish

I am afraid I have got some pretty basic questions about ehcache. I would like to use caching mechanism on clustered Glassfish without any significant infrastrucure.
As I know using ditributed cache with ehcache means that I have to use the terracotta server array, don't?
I am not so experienced in caching so could I use the ehcache on clustered glassfish that I just put some JAR into the classpath of Glassfish or deploy a WAR or something onto Glassfish and that's it? Do I have to use an external cache server anyway?
The replicated cache in ehcache doesn't need the terracotta server array, do it?
I would like to store a java Map object in the store which is going to be changed quite often. In this case the replicated cache is not best choice, as I know. The Hazelcast distributed cache needs any external cache server?
Thank you very much for your help in advance!
Have a nice day, experts!
Hazelcast doesn't need any externel server if you are running Java.
Basically add hazelcast.jar into your classpath. And from your application creata an Hazelcast instance:
HazelcastInstance hazelcast = Hazelcast.newHazelcastInstance(new Config());
then to get a distributed map:
Map map = hazelcast.getMap("myMap");
that's it. In this example I provided the default config which uses Multicast to discovery of the nodes. You can update and change any parameter.
For more information see Quick Start Tutorial
The replication feature in Ehcache does not require any server. You simply add the Ehcache jar to your web application and configure Ehcache to replicate to all cluster nodes. You can choose whether to automatically discover all GlassFish nodes using multicast or you can manually tell Ehcache where to find the other nodes. You can find the Ehcache replication configuration instructions here: http://ehcache.org/documentation/replication/rmi-replicated-caching#configuring-the-peer-provider
Hazelcast works similarly. See here for documentation: http://hazelcast.org/docs/3.0/manual/html/ch12s02.html

Spring cache of two Grails applications in the same machine (different Jetty server)

Hi I have one Grails application, it uses Spring cache. I want to clone it (say APP_A and APP_B) and deploy on separate it as each access different DB and has some different configuration.
Currently I have two copy of Jetty servers (JETTY_A, JETTY_B. different port). I put APP_A in Jetty_A and APP_B in Jetty_B.
I'm not familiar with Spring cache.
Is this deployment save? I mean, will there be any mix of cache between both? Because both using the same code base. So, the cache will use the same key name.
#cacheable("someCache")
SpringCache uses EHCache under the covers. The caches are in-process caches and they do not affect caches running in other processes on the same machine, unless you had explicitly configured distributed caching.
As #KenLiu said in his answer, Spring Cache is strictly in-process when using EHCache as it's cache provider. Since you are working with Grails, however, there are better alternatives that will require only minimal changes.
The Grails Cache Plugin is a offers a Spring Cache API-compatible cache abstraction over a number of (plugable) cache providers, including some, like the Redis provider, that allow you to cache between processes (and entire machines) very easily.

ibatis / mybatis caching within a restful webservice

I am using mybatis within a Jax-RS (Jersey) restful web app. So automatically, I dont have a session or state management.
Question is how can I use the caching features of mybatis ?
Caching in MyBatis is very straight forward. Per the documentation (pg 42 of the user manual http://mybatis.googlecode.com/svn/trunk/doc/en/MyBatis-3-User-Guide.pdf)
By default, there is no caching enabled, except for local session caching, which improves performance and is required to resolve circular dependencies. To enable a second level of caching, you simply need to add one line to your SQL Mapping file:
MyBatis 3 - User Guide
6 June 2011 43
<cache/>
Literally that’s it.
The common pitfalls I had while doing this:
On the mapper you add the cache element to; if you have dependent entities, make sure to explicitly flush the cache when required. Even though flushing is already done for you on insert, update, delete for the elements in the mappings you have set the cache element, sometimes you have to flush a cache due to updates/deletes/etc defined in different xml mappings.
Basically, when you're thinking about your caching, you should ask yourself, "When this entity is changed, do I want it to flush a cache for an entity in a different mapping?" If the answer is yes, use cache-ref element as opposed to just cache.
Ex from page 45 of the doc:
<cache-ref namespace=”com.someone.application.data.SomeMapper”/>

Resources