I have 2-node cluster running on the same host using MVCC and INVALIDATION_ASYNC (JGroups
udp) with Hibernate 3.3.1. Under load an Entity update in ClusterNodeA does sometimes does
not cause invalidation of same Entity in ClusterNodeB:
State in B's Cache (and in DB) after B updates UserSession:
| /com.doppelganger.domain.UserSession#1116 {item={hibernateVersion=40, boot=false,
loginTime=2009-03-26 09:05:48.0, icecastMount=null,
_subclass=com.doppelganger.domain.UserSession, macAddressMD5=null, serverSession=null,
enclosingSpace=null, userStates=0, creationDate=2009-03-26 09:05:48.0, deviceIdMD5=null,
_version=40, expirationTime=2009-03-26 10:06:55.0,
token=108fb802-d5ca-40eb-80bb-c347efa95b64, logoutTime=null,
_lazyPropertiesUnfetched=false, user=172}}
|
State in A's Cache at the same time:
| /com.doppelganger.domain.UserSession#1116 {item={hibernateVersion=39, boot=false,
loginTime=2009-03-26 09:05:48.0, icecastMount=null,
_subclass=com.doppelganger.domain.UserSession, macAddressMD5=null, serverSession=272,
enclosingSpace=205, userStates=0, creationDate=2009-03-26 09:05:48.0, deviceIdMD5=null,
_version=39, expirationTime=2009-03-26 10:06:55.0,
token=108fb802-d5ca-40eb-80bb-c347efa95b64, logoutTime=null,
_lazyPropertiesUnfetched=true, user=172}}
|
The correct state is hibernateVersion=40; serverSession=NULL (not the case in A).
Subsequent attempts to update this UserSession on A lead to StaleObjectStateException
because hibernateVersion is < 40.
Question:
Seems like the invalidation message from B (a) either never arrives at A or (b) is ignored
by A for some reason. Any hints on which loggers to turn up and for which messages to look
to determine whether it's (a) or (b)?
Possible workaround/solution?
Let's say lost invalidation messages are a possibility and the app just has to be able
to deal with it. Our app has a TX retry mechanism that retries StaleObjectStateException
(and other concurrent access-related exceptions). Seems like it'd be more reliable to
removeNode for Entity causing the exception before executing a retry. However, this
removal should be done locally only (and not be multicast to other nodes).
I see org.jboss.cache.config.Option.cacheModeLocal and
org.hibernate.cache.jbc2.util.CacheHelper.remove(Cache cache, Fqn region, Object key,
Option option). Unfortunately, there is no way to pass on Option to
org.hibernate.cache.jbc2.entity.TransactionAccess.remove(key). So it seems like the thing
to do is to call CacheHelper.removeNode(stuff, Option.cacheModeLocal=true) before TX retry
(would execute outside of tx). What do folks think?
View the original post :
http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4221377#...
Reply to the post :
http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&a...