[JBoss Cache: Core Edition] - Re: invalidation messages lost/ignored?
by dukehoops
The possible solution I described above works for me. The code's below, I would still appreciate peer review and feedback, particularly on:
-whether option.setCacheModeLocal(true) is enough to ensure non-propagation of the remove call (to other cluster nodes)
-why was cache getting into this (indefinite) state and whether that's to be expected or a sign of a bug/greater problem
| package com.doppelganger.framework.hibernate;
|
| import com.doppelganger.framework.cache.DGEntityTransactionalAccess;
| import javax.transaction.Transaction;
| import org.hibernate.HibernateException;
| import org.hibernate.StaleObjectStateException;
| import org.hibernate.cache.CacheKey;
| import org.hibernate.event.EventSource;
| import org.hibernate.event.FlushEvent;
| import org.hibernate.event.def.DefaultFlushEventListener;
| import org.hibernate.impl.SessionFactoryImpl;
| import org.hibernate.persister.entity.EntityPersister;
| import org.slf4j.Logger;
| import org.slf4j.LoggerFactory;
| import org.springframework.beans.factory.annotation.Autowired;
| import org.springframework.stereotype.Component;
| import org.springframework.transaction.jta.JtaTransactionManager;
|
| /**
| *
| * @author nikita
| */
| @Component("cacheUpdatingFlushEventListener")
| public class CacheUpdatingFlushEventListener extends DefaultFlushEventListener {
|
| final static private Logger LOG = LoggerFactory.getLogger(CacheUpdatingFlushEventListener.class);
| @Autowired
| private JtaTransactionManager jtaTransactionManager;
|
| @Override
| public void onFlush(FlushEvent event) throws HibernateException {
| try {
| super.onFlush(event);
| } catch (StaleObjectStateException ex) {
|
| //if possible, remove offending entity from 2nd level cache
| //remove offending ENTITY cache node (only locally - no cluster-wide propagation)
|
| Transaction tx = null;
| try {
| SessionFactoryImpl sfImpl = (SessionFactoryImpl) event.getSession().getSessionFactory();
| EntityPersister persister = sfImpl.getEntityPersister(ex.getEntityName());
| if (persister.hasCache()) {
| EventSource session = event.getSession();
| CacheKey ck = new CacheKey(
| ex.getIdentifier(),
| persister.getIdentifierType(),
| persister.getRootEntityName(),
| session.getEntityMode(),
| session.getFactory());
|
|
| if (persister.getCacheAccessStrategy() instanceof DGEntityTransactionalAccess) {
|
| LOG.debug("removing Entity cache node with key=" + ck + " after concurrency exception: " + ex);
|
| tx = jtaTransactionManager.getTransactionManager().suspend();
|
| DGEntityTransactionalAccess entityCacheAccessStrategy = (DGEntityTransactionalAccess) persister.getCacheAccessStrategy();
| entityCacheAccessStrategy.remove(ck, true);
| }
| }
| } catch (Throwable t) {
| LOG.error("error removing Entity cache node after detecting exception: " + ex + ". Proceeding to rethrow detected exception", t);
| } finally {
| if (tx != null) {
| try {
| jtaTransactionManager.getTransactionManager().resume(tx);
| } catch (Throwable t) {
| LOG.error("failed to resume a tx - INVESTIGATE!", t);
| }
| }
| //rethrow original exception
| throw ex;
| }
| }
| }
| }
|
| package com.doppelganger.framework.cache;
|
| import org.hibernate.cache.CacheException;
| import org.hibernate.cache.CacheKey;
| import org.hibernate.cache.jbc2.entity.EntityRegionImpl;
| import org.hibernate.cache.jbc2.entity.TransactionalAccess;
| import org.jboss.cache.config.Option;
|
| /**
| *
| * @author nikita
| */
| public class DGEntityTransactionalAccess extends TransactionalAccess {
|
| final private DGTransactionalAccessDelegate accessDelegate;
|
| public DGEntityTransactionalAccess(EntityRegionImpl region, DGTransactionalAccessDelegate delegate) {
| super(region, delegate);
| if (delegate == null) {
| throw new IllegalStateException("accessDelegate cannot be null and must wrap the same 'region' as passed to this constructor");
| }
| this.accessDelegate = delegate;
| }
|
| /**
| * same as TransactionalAccess.remove(key) except adds switch to NOT send replication/invalidation messages
| * @param key
| * @param localOnly
| * @throws org.hibernate.cache.CacheException
| */
| public void remove(CacheKey key, boolean localOnly) throws CacheException {
| if (localOnly) {
| Option option = new Option();
| option.setCacheModeLocal(true);
| getAccessDelegate().remove(key, option);
| } else {
| remove(key);
| }
| }
|
| /**
| * @return the accessDelegate
| */
| public DGTransactionalAccessDelegate getAccessDelegate() {
| return accessDelegate;
| }
| }
|
| /*
| * To change this template, choose Tools | Templates
| * and open the template in the editor.
| */
| package com.doppelganger.framework.cache;
|
| import org.hibernate.cache.CacheException;
| import org.hibernate.cache.CacheKey;
| import org.hibernate.cache.jbc2.BasicRegionAdapter;
| import org.hibernate.cache.jbc2.access.TransactionalAccessDelegate;
| import org.hibernate.cache.jbc2.util.CacheHelper;
| import org.jboss.cache.config.Option;
|
| /**
| *
| * @author nikita
| */
| public class DGTransactionalAccessDelegate extends TransactionalAccessDelegate {
|
| DGTransactionalAccessDelegate(BasicRegionAdapter adapter) {
| super(adapter);
| }
|
| /**
| * same as remove(key), but with an Option
| * @param key
| * @param option
| */
| void remove(CacheKey key, Option option) throws CacheException {
| region.ensureRegionRootExists();
| CacheHelper.remove(cache, regionFqn, key, option);
| //cache.removeNode(new Fqn(region, key));
| //cache.evict(new Fqn(region, key));
| }
| }
|
| /*
| * To change this template, choose Tools | Templates
| * and open the template in the editor.
| */
| package com.doppelganger.framework.cache;
|
| import org.hibernate.cache.CacheDataDescription;
| import org.hibernate.cache.CacheException;
| import org.hibernate.cache.access.AccessType;
| import org.hibernate.cache.access.EntityRegionAccessStrategy;
| import org.hibernate.cache.jbc2.entity.EntityRegionImpl;
| import org.jboss.cache.Cache;
|
| /**
| *
| * @author nikita
| */
| public class DGEntityRegionImpl extends EntityRegionImpl {
|
| public DGEntityRegionImpl(Cache jbcCache, String regionName, String regionPrefix, CacheDataDescription metadata) {
| super(jbcCache, regionName, regionPrefix, metadata);
| }
|
| /**
| * supply our own Entity TransactionalAccess impl; assume we don't need OptimisticTransactionalAccess (since we're using MVCC)
| * @param accessType
| * @return
| * @throws org.hibernate.cache.CacheException
| */
| @Override
| public EntityRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException {
| if (AccessType.READ_ONLY.equals(accessType)) {
| return new DGEntityReadOnlyAccess(this, new DGTransactionalAccessDelegate(this));
| }
| if (AccessType.TRANSACTIONAL.equals(accessType)) {
| return new DGEntityTransactionalAccess(this, new DGTransactionalAccessDelegate(this));
| }
|
| throw new CacheException("unsupported access type [" + accessType.getName() + "]");
| }
| }
|
|
View the original post : http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4221430#4221430
Reply to the post : http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&p=4221430
17 years
[Installation, Configuration & DEPLOYMENT] - Problem when restarting: javax.naming.NameNotFoundException:
by oawofolu
Hi all,
I'm a newbie to JBoss and I hope this is an easy question. Basically I'm having trouble with shutting down the server (JBoss 5.0, CentOS 5):
[root@XXXDD standard-report]# $JBOSS_HOME/bin/shutdown.sh -S
Exception in thread "main" javax.naming.NameNotFoundException: jmx not bound
at org.jnp.server.NamingServer.getBinding(NamingServer.java:564)
at org.jnp.server.NamingServer.getBinding(NamingServer.java:572)
at org.jnp.server.NamingServer.getObject(NamingServer.java:578)
at org.jnp.server.NamingServer.lookup(NamingServer.java:288)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:305)
at sun.rmi.transport.Transport$1.run(Transport.java:159)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:255)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:233)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:142)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:178)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:132)
at $Proxy0.lookup(Unknown Source)
at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:669)
at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:629)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at org.jboss.Shutdown.main(Shutdown.java:218)
Now the problem is that the application I deployed has nothing to do with JMX (it's a JRuby application...)
Also, the shutdown was working before, it only broke when I attempted to start the server using:
$JBOSS_HOME/bin/run.sh -b 0.0.0.0 >& /dev/null &
PLEASE HELP!!! (Need a fix urgently as I'm supposed to have been done with tthe deployment by now...)
Thanks in advance
View the original post : http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4221424#4221424
Reply to the post : http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&p=4221424
17 years