-
1. Re: locking cache for updates
pruivo Mar 17, 2015 7:27 AM (in response to yairogen)Hi Yair,
Can you elaborate "synchronize a cache value between nodes"?
With or without transaction support, we maintain data consistency.
Cheers,
Pedro
-
2. Re: locking cache for updates
yairogen Mar 18, 2015 9:02 AM (in response to pruivo)I have a 2 node cluster with one owner per entry. My cache entry value is a complex object that contains a list of other objects among other things.
I want to make sure the following doesn't happen:
Node A reads cache entry. Gets list of size 4.
Node B reads cache entry for the same key and also gets list of size 4.Node A adds an object to the list and in parallel node B does the same.
Now each node updates the cache. We end up with list of size 5 while we really would have wanted size of 6.
-
3. Re: locking cache for updates
pruivo Mar 18, 2015 1:06 PM (in response to yairogen)1 of 1 people found this helpfulHi,
Yes, in your case you need transactions with pessimistic lock. You can synchronize your data by acquiring the lock before reading it. for example
transactionManager.begin(); cache.getAdvancedCache().lock("my-list"); //1 network round-trip to acquire the lock (if the value does not exists in the node) List<Object> list = cache.get("my-list"); //1 network round-trip (if the value does not exists in the node) list.add(newObject); cache.put("my-list", list); //local only operation transactionManager.commit(); //1 network round-trip to send the updates and release the lock (if the value does not exists in the node)
You don't need to lock if you force a write lock in the read:
List<Object> list = cache.getAdvancedCache().withFlags(FORCE_WRITE_LOCK).get("my-list");
Another alternative that does not requires transactions is to use the replace() method, but I have no idea how the performance is. example
do { List<Object> oldList = cache.get("my-list"); List<Object> newList = copyListAndAddObject(oldList, newObject); } while(!cache.replace("my-list", oldList, newList));
The get() and replace() have a single network round-trip if the value does not exists locally.
-
4. Re: locking cache for updates
yairogen Mar 19, 2015 2:48 AM (in response to pruivo)Thanks.
Using transactions is faster than using replace?
what is the penalty on cache locks within the same node when using transactions? I.e. 2 threads on the same node what to update the cache and it is stored locally. And how would that compare, performance wise, with 2 threads updating the cache whilst it resides in another node?
-
5. Re: locking cache for updates
pruivo Mar 19, 2015 6:32 AM (in response to yairogen)Yair Ogen wrote:
Using transactions is faster than using replace?
Unfortunately I can't answer that question because it depends on multiple factors (mainly the application workload). Theoretically speaking, if the list needs to be updated frequently, the transactional approach should be faster than the replace.
Yair Ogen wrote:
what is the penalty on cache locks within the same node when using transactions? I.e. 2 threads on the same node what to update the cache and it is stored locally. And how would that compare, performance wise, with 2 threads updating the cache whilst it resides in another node?
If it is stored locally, the performance should be the same as acquiring java locks. If it is stored remotely, you need a network round trip to acquire the lock. With 2 threads, one of the requests is able to acquire the lock and another will block until it is released.
-
6. Re: locking cache for updates
yairogen Mar 19, 2015 7:37 AM (in response to pruivo)Wouldn't an optimistic lock be better in terms of performance if in the rare cases where the data is stale my code will retry?
-
7. Re: locking cache for updates
yairogen Mar 26, 2015 6:48 AM (in response to yairogen)@Pedro, would this configuration suffice for the creation of the TC Manager?
transaction().transactionManagerLookup(new JBossStandaloneJTAManagerLookup()).lockingMode(LockingMode.PESSIMISTIC)