Yesterday, one of our consultants (Chris Harris) brought up a very interesting point
regarding local changes on direct custom object or collections references that are
cached:
anonymous wrote : I have a customer who is trying to use TreeCache 1.4 directly and our
doing something like : (Note I am writing this code directly in this case so it may not
compile ;-) ):
|
| //within the transaction
|
| List aList = new ArrayList();
| aList.add("Test1");
| tree.put("/a/b/c", "name", aList);
|
| aList.add("Test2");
|
| //transaction commit
|
| //outside the transaction
|
| aList.add("Test3");
|
| They are experiencing that if they add something to the List within the cache after
the put then the new element within the list is also cached. I would have not expected
this as I always thought you need to explicitly call put to add the object back into the
cache.
|
| They are also experiencing that "Test3" is also added the the cache but is
not replicated until the next transaction is commits. Again I don't think this is
right.
|
| The design of their application involves putting a layer in front of TreeCache that
exposes simple put and get methods to the users of their API. They are considered that
users may now be adding data to the cache that they did not intend to add.
|
| Can someone validate if this is the expected behavior of TreeCache.
|
| The workaround I have is to clone the object before giving it back to the client but
they is not a very nice solution.
Here's the response that I gave to him:
anonymous wrote : When it comes to standard JBoss Cache usage, transactional work is
primarily used to limit replication which is costly. Local changes on direct custom object
or collections references will be visible locally.
|
| When it comes to pessimistic locking, JBossCache maintains a direct reference to the
object stored in memory, so adding an element to a list after a put will be visible in the
cached element, but the thing to bear in mind is that if transaction commits, it'll
get replicated and if it rollbacks, it won't get replicated and the local
modifications via put will be rollbacked, in this case, the put will be reverted and
won't be visible.
|
| Even though the changes the cached changes will be visible after
"aList.add("Test2");", this will only be visible within that
transaction. Locking will prevent that other transactions act on the cached object.
|
| Same happens with OL even though changes within a transaction are maintained in a
workspace. If you're within a transaction and you call get(), the value returned will
be looked up in the workspace for the transaction, so in your case, a get call after
"aList.add("Test2");" will return a list with Test2 too. We also store
direct references to objects in OL's workspaces.
|
| Outside of a transaction, unless you do a put call, there won't be a replication,
which is why adding to a List does not produce a replication. You'd need to use
PojoCache to get this type of behavior.
Chris is pretty much now forced to clone inputs or returns to the cache to avoid this type
of issue. Thoughts?
Is this maybe an option we wanna be providing in the future? or is this is an edge case
that the user must deal with?
In core JBossCache, we have no control over the references to these objects.
View the original post :
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4117068#...
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&a...