📄 basicregionadapter.java
字号:
/* * Hibernate, Relational Persistence for Idiomatic Java * * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are * distributed under license by Red Hat Middleware LLC. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU * Lesser General Public License, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution; if not, write to: * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */package org.hibernate.cache.jbc2;import java.util.HashMap;import java.util.Map;import java.util.Set;import javax.transaction.SystemException;import javax.transaction.Transaction;import javax.transaction.TransactionManager;import org.hibernate.cache.CacheException;import org.hibernate.cache.Region;import org.hibernate.cache.jbc2.util.CacheHelper;import org.hibernate.cache.jbc2.util.NonLockingDataVersion;import org.jboss.cache.Cache;import org.jboss.cache.Fqn;import org.jboss.cache.Node;import org.jboss.cache.NodeSPI;import org.jboss.cache.config.Configuration;import org.jboss.cache.config.Option;import org.jboss.cache.config.Configuration.NodeLockingScheme;import org.jboss.cache.notifications.annotation.CacheListener;import org.jboss.cache.optimistic.DataVersion;import org.slf4j.Logger;import org.slf4j.LoggerFactory;/** * General support for writing {@link Region} implementations for JBoss Cache * 2.x. * * @author Steve Ebersole */@CacheListenerpublic 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 RegionRootListener listener; public BasicRegionAdapter(Cache jbcCache, String regionName, String regionPrefix) { this.jbcCache = jbcCache; this.transactionManager = jbcCache.getConfiguration().getRuntimeConfig().getTransactionManager(); this.regionName = regionName; this.regionFqn = createRegionFqn(regionName, regionPrefix); optimistic = jbcCache.getConfiguration().getNodeLockingScheme() == NodeLockingScheme.OPTIMISTIC; log = LoggerFactory.getLogger(getClass()); activateLocalClusterNode(); log.debug("Created Region for " + regionName + " -- regionPrefix is " + regionPrefix); } protected abstract Fqn<String> createRegionFqn(String regionName, String regionPrefix); protected void activateLocalClusterNode() { // Regions can get instantiated in the course of normal work (e.g. // a named query region will be created the first time the query is // executed), so suspend any ongoing tx Transaction tx = suspend(); try { Configuration cfg = jbcCache.getConfiguration(); if (cfg.isUseRegionBasedMarshalling()) { org.jboss.cache.Region jbcRegion = jbcCache.getRegion(regionFqn, true); ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); if (classLoader == null) { classLoader = getClass().getClassLoader(); } jbcRegion.registerContextClassLoader(classLoader); if ( !jbcRegion.isActive() ) { jbcRegion.activate(); } } // // If we are using replication, we may remove the root node// // 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()) // || CacheHelper.isClusteredInvalidation(cfg.getCacheMode())) {// listener = new RegionRootListener();// jbcCache.addCacheListener(listener);// } regionRoot = jbcCache.getRoot().getChild( regionFqn ); if (regionRoot == null || !regionRoot.isValid()) { // 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); } } if (!regionRoot.isResident()) { regionRoot.setResident(true); } } catch (Exception e) { throw new CacheException(e.getMessage(), e); } finally { if (tx != null) resume(tx); } } private void establishRegionRootNode() { synchronized (regionRootMutex) { // If we've been blocking for the mutex, perhaps another // thread has already reestablished the root. // In case the node was reestablised via replication, confirm it's // marked "resident" (a status which doesn't replicate) if (regionRoot != null && regionRoot.isValid()) { return; } // For pessimistic locking, we just want to toss out our ref // to any old invalid root node and get the latest (may be null) if (!optimistic) { regionRoot = jbcCache.getRoot().getChild( regionFqn ); return; } // The rest only matters for optimistic locking, where we // need to establish the proper data version on the region root // Don't hold a transactional lock for this Transaction tx = suspend(); Node newRoot = null; try { // Make sure the root node for the region exists and // has a DataVersion that never complains newRoot = jbcCache.getRoot().getChild( regionFqn ); if (newRoot == null || !newRoot.isValid()) { // Establish the region root node with a non-locking data version DataVersion version = optimistic ? NonLockingDataVersion.INSTANCE : null; newRoot = CacheHelper.addNode(jbcCache, regionFqn, true, true, version); } else if (newRoot instanceof NodeSPI) { // FIXME Hacky workaround to JBCACHE-1202 if ( !( ( ( NodeSPI ) newRoot ).getVersion() instanceof NonLockingDataVersion ) ) { ((NodeSPI) newRoot).setVersion(NonLockingDataVersion.INSTANCE); } } // Never evict this node newRoot.setResident(true); } finally { resume(tx); regionRoot = newRoot; } } } public String getName() { return regionName; } public Cache getCacheInstance() { return jbcCache; } public Fqn getRegionFqn() { return regionFqn; } /** * Checks for the validity of the root cache node for this region, * creating a new one if it does not exist or is invalid, and also * ensuring that the root node is marked as resident. Suspends any * transaction while doing this to ensure no transactional locks are held * on the region root. * * TODO remove this once JBCACHE-1250 is resolved.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -