-
1. Re: Invalidation-only cache
mircea.markus Sep 22, 2009 9:58 AM (in response to adamw)can't you do the get call outside a transaction? You can use TransactionManager.suspend/resume if you need to do some more work in tx after refreshing the cache.
-
2. Re: Invalidation-only cache
adamw Sep 23, 2009 2:40 AM (in response to adamw)Hello,
but if I call get() in the TX that did the changes, I want to get a re-calculated value basing on the changed persistent store. Other threads should get of course the old value.
Adam -
3. Re: Invalidation-only cache
mircea.markus Sep 23, 2009 5:07 AM (in response to adamw)even within a TX, I would expect that if you ask for a node that is not in the memory the cache store still to be queried and data fetched from there. Just for me to make sure I get it right, you have something like:
tx.start() cache.remove(fqn); //this will clear data from both memory AND cache store cache.get(fqn);// this should look into both memory AND cache store tx.commit();
So, IMO, disregarding weather you do the second call within a tx or not, it should still query the cache store. Actually I'm a bit confused that when the sequence runs outside of a tx the cache store returns a non null value, give the fact that you specifically performed a remove on the same node. -
4. Re: Invalidation-only cache
adamw Sep 23, 2009 6:15 AM (in response to adamw)Hello,
Well, if I call cache.remove(fqn) in a tx, then any subsequent calls return null, without hitting the cache loader. Only after the tx is commited, the cache loader is queried. (In the no-tx scenario it behaves as if the tx was commited immediately after the operation.) That's what my experiments show ;)
This behaviour (I think) is consistent with this bug:
https://jira.jboss.org/jira/browse/JBCACHE-352
Adam -
5. Re: Invalidation-only cache
mircea.markus Sep 23, 2009 7:31 AM (in response to adamw)ah I see. Out of ideas then :(
-
6. Re: Invalidation-only cache
adamw Sep 23, 2009 8:16 AM (in response to adamw)Heh, I didn't expect that my use case will be so uncommon. It seems a relatively simple idea to store some computed values and invalidate them when the underlying data changes. But well ... :)
Adam -
7. Re: Invalidation-only cache
mircea.markus Sep 23, 2009 9:07 AM (in response to adamw)Heh, I didn't expect that my use case will be so uncommon. It seems a relatively simple idea to store some computed values and invalidate them when the underlying data changes. But well ... :)
Well apparently this is the first time one asks for this functionality :)
One thing you can try: what about replace the cache.remove call, with a cache.put(newValue), and fetch the new value outside the transaction. -
8. Re: Invalidation-only cache
adamw Sep 23, 2009 9:14 AM (in response to adamw)Hello,
yes, I'm doing that now for a limited number of keys (eagerly putting them in the cache instead of removing the whole node), although I'm doing it inside the TX (I want the new values to be calculated basing on the data modified in the TX), however I can't do that for all keys, as that would take too much time. The whole point of using a cache loader is to be able to compute those values lazily.
Adam -
9. Re: Invalidation-only cache
manik Sep 23, 2009 12:55 PM (in response to adamw)I think you are using the cache loader in an incorrect way. CLs are designed to be a persistent (and overflow) extension to memory and should never be sued to store a different form of data. And should also never change externally outside the cache system.
If you want to cache stuff from a data source which contains a different form of data, or that can be updated externally, I recommend looking at how Hibernate implements a 2nd level cache as this pattern is similar. Basically your code would look up the cache. If it is not in the cache, look in the data store, retrieve and cache before returning. And periodically (or based on some other trigger) invalidate what's in the cache. -
10. Re: Invalidation-only cache
adamw Sep 24, 2009 2:56 AM (in response to adamw)Hello,
well, from what I've seen in CacheHelper Hibernate is simply calling get() and put(). However in my case this doesn't work, as I run the cache in INVALIDATION_SYNC mode. This means that when I call put() on node1, an invalidation message is sent to other nodes. Then, when node 2 wants to retrieve the object, it sees that there's no value, so it calculates the value and calls put(), which invalidates the node on node1, and so on. In fact, what I would need are three operations: invalidation of a node in a cluster, local-get and local-put (without invalidating).
Using cacheloader (well, I admin, hacking around it ;) ) allowed me to get a local-put. Maybe I'll see what the CL are doing behind the scenes :)
Adam -
11. Re: Invalidation-only cache
manik Sep 24, 2009 5:33 AM (in response to adamw)Have a look at Hibernate, again. :-) They too use INVALIDATION, and there is a way to deal with this - it's called putForExternalRead().
As for the CL approach, that will not work, this scenario is not what the CL is designed for. -
12. Re: Invalidation-only cache
adamw Sep 24, 2009 7:52 AM (in response to adamw)Ah yes, didn't notice it, thanks a lot! :)
Adam -
13. Re: Invalidation-only cache
adamw Sep 28, 2009 4:50 AM (in response to adamw)One more question though - do I understand right from the javadoc that putForExternalRead is non-transactional? Meaning that if a change something in a TX in the persistent store, and then call putForExternalRead with the changes, other transactions will see the change, making it a dirty read?
Although I'll probably won't be able to use it anyway, as I'm not able to deploy cache > 2 on AS 4.2 ;) (Hibernate stops finding the datasource in jndi ...)
Adam -
14. Re: Invalidation-only cache
adamw Sep 28, 2009 4:58 AM (in response to adamw)Another idea, using JBC 1.4.1; for put operations, which shouldn't cause invalidation, maybe I could use an Option with cache mode == LOCAL. For the remove operation, I could use INVALIDATION_SYNC, which should propagate. Do you see any obstacles here? :)
Adam