[hibernate-commits] Hibernate SVN: r14263 - in core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2: access and 4 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Sun Dec 23 09:59:07 EST 2007


Author: bstansberry at jboss.com
Date: 2007-12-23 09:59:07 -0500 (Sun, 23 Dec 2007)
New Revision: 14263

Modified:
   core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/BasicRegionAdapter.java
   core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/OptimisticTransactionalAccessDelegate.java
   core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/TransactionalAccessDelegate.java
   core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/OptimisticTransactionalAccess.java
   core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/TransactionalAccess.java
   core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/OptimisticTransactionalAccess.java
   core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/TransactionalAccess.java
   core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/query/QueryResultsRegionImpl.java
   core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/timestamp/TimestampsRegionImpl.java
Log:
Update handling of deletion of the region root node

Modified: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/BasicRegionAdapter.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/BasicRegionAdapter.java	2007-12-23 14:55:36 UTC (rev 14262)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/BasicRegionAdapter.java	2007-12-23 14:59:07 UTC (rev 14263)
@@ -40,11 +40,16 @@
 import org.jboss.cache.config.Configuration.NodeLockingScheme;
 import org.jboss.cache.notifications.annotation.CacheListener;
 import org.jboss.cache.notifications.annotation.NodeCreated;
+import org.jboss.cache.notifications.annotation.NodeRemoved;
 import org.jboss.cache.notifications.event.NodeCreatedEvent;
+import org.jboss.cache.notifications.event.NodeRemovedEvent;
 import org.jboss.cache.optimistic.DataVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import org.hibernate.cache.CacheException;
 import org.hibernate.cache.Region;
+import org.hibernate.cache.jbc2.builder.JndiMultiplexingCacheInstanceManager;
 import org.hibernate.cache.jbc2.util.CacheHelper;
 import org.hibernate.cache.jbc2.util.NonLockingDataVersion;
 
@@ -56,16 +61,20 @@
  */
 @CacheListener
 public abstract class BasicRegionAdapter implements Region {
+   
+    
     public static final String ITEM = CacheHelper.ITEM;
 
     protected final Cache jbcCache;
     protected final String regionName;
     protected final Fqn regionFqn;
+    protected Node regionRoot;
     protected final boolean optimistic;
-    
     protected final TransactionManager transactionManager;
+    protected final Logger log;
+    protected final Object regionRootMutex = new Object();
 
-    protected SetResidentListener listener;
+    protected RegionRootListener listener;
     
     public BasicRegionAdapter(Cache jbcCache, String regionName, String regionPrefix) {
         this.jbcCache = jbcCache;
@@ -73,6 +82,7 @@
         this.regionName = regionName;
         this.regionFqn = createRegionFqn(regionName, regionPrefix);
         optimistic = jbcCache.getConfiguration().getNodeLockingScheme() == NodeLockingScheme.OPTIMISTIC;
+        log = LoggerFactory.getLogger(getClass());
         activateLocalClusterNode();
     }
 
@@ -97,33 +107,50 @@
             // and then need to re-add it. In that case, the fact
             // that it is resident will not replicate, so use a listener
             // to set it as resident
-            if (CacheHelper.isClusteredReplication(cfg.getCacheMode())) {
-                listener = new SetResidentListener();
+            if (CacheHelper.isClusteredReplication(cfg.getCacheMode()) 
+                  || CacheHelper.isClusteredInvalidation(cfg.getCacheMode())) {
+                listener = new RegionRootListener();
                 jbcCache.addCacheListener(listener);
             }
             
-            // Make sure the root node for the region exists and 
-            // has a DataVersion that never complains
-            Node regionRoot = jbcCache.getRoot().getChild( regionFqn );
-            if (regionRoot == null) {                
-                // Establish the region root node with a non-locking data version
-                DataVersion version = optimistic ? NonLockingDataVersion.INSTANCE : null;
-                regionRoot = CacheHelper.addNode(jbcCache, regionFqn, true, true, version);    
-            }
-            else if (optimistic && regionRoot instanceof NodeSPI) {
-                // FIXME Hacky workaround to JBCACHE-1202
-                if ( !( ( ( NodeSPI ) regionRoot ).getVersion() instanceof NonLockingDataVersion ) ) {
-                    ((NodeSPI) regionRoot).setVersion(NonLockingDataVersion.INSTANCE);
-                }
-            }
-            // Never evict this node
-            regionRoot.setResident(true);
+            establishRegionRootNode();
         }
         catch (Exception e) {
             throw new CacheException(e.getMessage(), e);
         }
     }
 
+    private void establishRegionRootNode()
+    {
+        synchronized (regionRootMutex) {
+            if (regionRoot != null && regionRoot.isValid())
+                return;
+            // Don't hold a transactional lock for this 
+            Transaction tx = suspend();
+            try {
+                 // Make sure the root node for the region exists and 
+                 // has a DataVersion that never complains
+                 regionRoot = jbcCache.getRoot().getChild( regionFqn );
+                 if (regionRoot == null) {                
+                     // Establish the region root node with a non-locking data version
+                     DataVersion version = optimistic ? NonLockingDataVersion.INSTANCE : null;
+                     regionRoot = CacheHelper.addNode(jbcCache, regionFqn, true, true, version);    
+                 }
+                 else if (optimistic && regionRoot instanceof NodeSPI) {
+                     // FIXME Hacky workaround to JBCACHE-1202
+                     if ( !( ( ( NodeSPI ) regionRoot ).getVersion() instanceof NonLockingDataVersion ) ) {
+                          ((NodeSPI) regionRoot).setVersion(NonLockingDataVersion.INSTANCE);
+                     }
+                 }
+                // Never evict this node
+                regionRoot.setResident(true);
+            }
+            finally {
+                resume(tx);
+            }
+        }
+    }
+
     public String getName() {
         return regionName;
     }
@@ -135,12 +162,29 @@
     public Fqn getRegionFqn() {
         return regionFqn;
     }
+    
+    /**
+     * If the cache is configured for optimistic locking, checks for the 
+     * validity of the root cache node for this region,
+     * creating a new one if it does not exist or is invalid.  Suspends any 
+     * transaction while doing this to ensure no transactional locks are held 
+     * on the region root.
+     * 
+     * This is only needed for optimistic locking, as with optimistic the
+     * region root node has a special version that must be established.
+     * 
+     * TODO remove this once JBCACHE-1250 is resolved.
+     */
+    public void ensureRegionRootExists() {
+       if (optimistic && (regionRoot == null || !regionRoot.isValid()))
+          establishRegionRootNode();
+    }
 
     public void destroy() throws CacheException {
         try {
             // NOTE : this is being used from the process of shutting down a
             // SessionFactory. Specific things to consider:
-            // (1) this clearing of the region should not propogate to
+            // (1) this clearing of the region should not propagate to
             // other nodes on the cluster (if any); this is the
             // cache-mode-local option bit...
             // (2) really just trying a best effort to cleanup after
@@ -321,11 +365,12 @@
     }
     
     @CacheListener
-    public class SetResidentListener {
+    public class RegionRootListener {
         
         @NodeCreated
         public void nodeCreated(NodeCreatedEvent event) {
             if (!event.isPre() && event.getFqn().equals(getRegionFqn())) {
+                log.debug("Node created for " + getRegionFqn());
                 Node regionRoot = jbcCache.getRoot().getChild(getRegionFqn());
                 regionRoot.setResident(true);
             }

Modified: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/OptimisticTransactionalAccessDelegate.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/OptimisticTransactionalAccessDelegate.java	2007-12-23 14:55:36 UTC (rev 14262)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/OptimisticTransactionalAccessDelegate.java	2007-12-23 14:59:07 UTC (rev 14263)
@@ -27,11 +27,11 @@
 import org.hibernate.cache.CacheException;
 import org.hibernate.cache.access.CollectionRegionAccessStrategy;
 import org.hibernate.cache.access.EntityRegionAccessStrategy;
+import org.hibernate.cache.jbc2.BasicRegionAdapter;
+import org.hibernate.cache.jbc2.TransactionalDataRegionAdapter;
 import org.hibernate.cache.jbc2.util.CacheHelper;
 import org.hibernate.cache.jbc2.util.DataVersionAdapter;
 import org.hibernate.cache.jbc2.util.NonLockingDataVersion;
-import org.jboss.cache.Cache;
-import org.jboss.cache.Fqn;
 import org.jboss.cache.config.Option;
 import org.jboss.cache.optimistic.DataVersion;
 
@@ -51,9 +51,9 @@
 
     protected final CacheDataDescription dataDescription;
 
-    public OptimisticTransactionalAccessDelegate(Cache cache, Fqn regionFqn, CacheDataDescription dataDescription) {
-        super(cache, regionFqn);
-        this.dataDescription = dataDescription;
+    public OptimisticTransactionalAccessDelegate(TransactionalDataRegionAdapter region) {
+        super(region);
+        this.dataDescription = region.getCacheDataDescription();
     }
 
     /**
@@ -63,6 +63,8 @@
      */
     @Override
     public void evict(Object key) throws CacheException {
+        
+        region.ensureRegionRootExists();
 
         Option opt = NonLockingDataVersion.getInvocationOption();
         CacheHelper.remove(cache, regionFqn, key, opt);
@@ -76,6 +78,18 @@
     public void evictAll() throws CacheException {
 
         evictOrRemoveAll();
+    }    
+    
+    /**
+     * Overrides the {@link TransactionalAccessDelegate#get(Object, long) superclass}
+     * by {@link BasicRegionAdapter#ensureRegionRootExists() ensuring the root
+     * node for the region exists} before making the call.
+     */
+    @Override
+    public Object get(Object key, long txTimestamp) throws CacheException
+    {
+        region.ensureRegionRootExists();
+        return super.get(key, txTimestamp);
     }
 
     /**
@@ -85,6 +99,8 @@
      */
     @Override
     public boolean insert(Object key, Object value, Object version) throws CacheException {
+        
+        region.ensureRegionRootExists();
 
         Option opt = getDataVersionOption(version, null);
         CacheHelper.put(cache, regionFqn, key, value, opt);
@@ -94,6 +110,8 @@
     @Override
     public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
             throws CacheException {
+        
+        region.ensureRegionRootExists();
 
         // We ignore minimalPutOverride. JBossCache putForExternalRead is
         // already about as minimal as we can get; it will promptly return
@@ -104,6 +122,8 @@
 
     @Override
     public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException {
+        
+        region.ensureRegionRootExists();
 
         Option opt = getDataVersionOption(version, version);
         return CacheHelper.putForExternalRead(cache, regionFqn, key, value, opt);
@@ -111,6 +131,8 @@
 
     @Override
     public void remove(Object key) throws CacheException {
+        
+        region.ensureRegionRootExists();
 
         Option opt = NonLockingDataVersion.getInvocationOption();
         CacheHelper.remove(cache, regionFqn, key, opt);
@@ -125,6 +147,8 @@
     @Override
     public boolean update(Object key, Object value, Object currentVersion, Object previousVersion)
             throws CacheException {
+        
+        region.ensureRegionRootExists();
 
         Option opt = getDataVersionOption(currentVersion, previousVersion);
         CacheHelper.put(cache, regionFqn, key, value, opt);
@@ -132,6 +156,7 @@
     }
 
     private Option getDataVersionOption(Object currentVersion, Object previousVersion) {
+        
         DataVersion dv = (dataDescription != null && dataDescription.isVersioned()) ? new DataVersionAdapter(
                 currentVersion, previousVersion, dataDescription.getVersionComparator(), dataDescription.toString())
                 : NonLockingDataVersion.INSTANCE;
@@ -141,6 +166,7 @@
     }
 
     private void evictOrRemoveAll() {
+       
         Option opt = NonLockingDataVersion.getInvocationOption();
         CacheHelper.removeAll(cache, regionFqn, opt);
         

Modified: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/TransactionalAccessDelegate.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/TransactionalAccessDelegate.java	2007-12-23 14:55:36 UTC (rev 14262)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/TransactionalAccessDelegate.java	2007-12-23 14:59:07 UTC (rev 14263)
@@ -27,6 +27,7 @@
 import org.hibernate.cache.access.CollectionRegionAccessStrategy;
 import org.hibernate.cache.access.EntityRegionAccessStrategy;
 import org.hibernate.cache.access.SoftLock;
+import org.hibernate.cache.jbc2.BasicRegionAdapter;
 import org.hibernate.cache.jbc2.util.CacheHelper;
 import org.jboss.cache.Cache;
 import org.jboss.cache.Fqn;
@@ -46,10 +47,12 @@
 
     protected final Cache cache;
     protected final Fqn regionFqn;
+    protected final BasicRegionAdapter region;
 
-    public TransactionalAccessDelegate(Cache cache, Fqn regionFqn) {
-        this.cache = cache;
-        this.regionFqn = regionFqn;
+    public TransactionalAccessDelegate(BasicRegionAdapter adapter) {
+        this.region = adapter;
+        this.cache = adapter.getCacheInstance();
+        this.regionFqn = adapter.getRegionFqn();
     }
 
     public Object get(Object key, long txTimestamp) throws CacheException {

Modified: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/OptimisticTransactionalAccess.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/OptimisticTransactionalAccess.java	2007-12-23 14:55:36 UTC (rev 14262)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/OptimisticTransactionalAccess.java	2007-12-23 14:59:07 UTC (rev 14263)
@@ -42,8 +42,7 @@
     public OptimisticTransactionalAccess(CollectionRegionImpl region) {
         
         // We use a different delegate than the non-optimistic superclass default
-        super(region, new OptimisticTransactionalAccessDelegate(region.getCacheInstance(), region.getRegionFqn(),
-                region.getCacheDataDescription()));
+        super(region, new OptimisticTransactionalAccessDelegate(region));
     }
 
 }

Modified: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/TransactionalAccess.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/TransactionalAccess.java	2007-12-23 14:55:36 UTC (rev 14262)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/TransactionalAccess.java	2007-12-23 14:59:07 UTC (rev 14263)
@@ -52,7 +52,7 @@
      * @param region the region to which this provides access
      */
     public TransactionalAccess(CollectionRegionImpl region) {
-        this(region, new TransactionalAccessDelegate(region.getCacheInstance(), region.getRegionFqn()));
+        this(region, new TransactionalAccessDelegate(region));
     }
 
     /**

Modified: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/OptimisticTransactionalAccess.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/OptimisticTransactionalAccess.java	2007-12-23 14:55:36 UTC (rev 14262)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/OptimisticTransactionalAccess.java	2007-12-23 14:59:07 UTC (rev 14263)
@@ -41,7 +41,6 @@
      * @param region The region\ to which this is providing access
      */
     public OptimisticTransactionalAccess(EntityRegionImpl region) {
-        super(region, new OptimisticTransactionalAccessDelegate(region.getCacheInstance(), region.getRegionFqn(),
-                region.getCacheDataDescription()));
+        super(region, new OptimisticTransactionalAccessDelegate(region));
     }
 }

Modified: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/TransactionalAccess.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/TransactionalAccess.java	2007-12-23 14:55:36 UTC (rev 14262)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/TransactionalAccess.java	2007-12-23 14:59:07 UTC (rev 14263)
@@ -46,7 +46,7 @@
     private final TransactionalAccessDelegate delegate;
 
     public TransactionalAccess(EntityRegionImpl region) {
-        this(region, new TransactionalAccessDelegate(region.getCacheInstance(), region.getRegionFqn()));
+        this(region, new TransactionalAccessDelegate(region));
     }
 
     protected TransactionalAccess(EntityRegionImpl region, TransactionalAccessDelegate delegate) {

Modified: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/query/QueryResultsRegionImpl.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/query/QueryResultsRegionImpl.java	2007-12-23 14:55:36 UTC (rev 14262)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/query/QueryResultsRegionImpl.java	2007-12-23 14:59:07 UTC (rev 14263)
@@ -75,6 +75,9 @@
     }
 
     public void evict(Object key) throws CacheException {
+       
+        ensureRegionRootExists();
+        
         Option opt = getNonLockingDataVersionOption(false);
         if (localOnly)
             opt.setCacheModeLocal(true);
@@ -91,6 +94,8 @@
     }
 
     public Object get(Object key) throws CacheException {
+       
+        ensureRegionRootExists();
 
         // Don't hold the JBC node lock throughout the tx, as that
         // prevents updates
@@ -102,6 +107,8 @@
     }
 
     public void put(Object key, Object value) throws CacheException {
+       
+        ensureRegionRootExists();
 
         // Here we don't want to suspend the tx. If we do:
         // 1) We might be caching query results that reflect uncommitted
@@ -110,9 +117,9 @@
         // 2) No tx == immediate replication. More overhead, plus we
         // spread issue #1 above around the cluster
 
-        // Add a zero (or quite low) timeout option so we don't block
+        // Add a zero (or quite low) timeout option so we don't block.
         // Ignore any TimeoutException. Basically we forego caching the
-        // query result in order to avoid blocking for concurrent reads.
+        // query result in order to avoid blocking.
         // Reads are done with suspended tx, so they should not hold the
         // lock for long.  Not caching the query result is OK, since
         // any subsequent read will just see the old result with its

Modified: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/timestamp/TimestampsRegionImpl.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/timestamp/TimestampsRegionImpl.java	2007-12-23 14:55:36 UTC (rev 14262)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/timestamp/TimestampsRegionImpl.java	2007-12-23 14:59:07 UTC (rev 14263)
@@ -85,6 +85,9 @@
     }
 
     public void evict(Object key) throws CacheException {
+       
+        ensureRegionRootExists();
+        
         // TODO Is this a valid operation on a timestamps cache?
         Option opt = getNonLockingDataVersionOption(true);
         CacheHelper.removeNode(getCacheInstance(), getRegionFqn(), key, opt);
@@ -102,6 +105,9 @@
 
         Object value = localCache.get(key);
         if (value == null) {
+           
+            ensureRegionRootExists();
+            
             value = suspendAndGet(key, null, false);
             if (value != null)
                 localCache.put(key, value);
@@ -110,6 +116,8 @@
     }
 
     public void put(Object key, Object value) throws CacheException {
+       
+        ensureRegionRootExists();
 
         // Don't hold the JBC node lock throughout the tx, as that
         // prevents reads and other updates




More information about the hibernate-commits mailing list