[jboss-cvs] JBossAS SVN: r60250 - branches/Branch_4_2/ejb3/src/main/org/jboss/ejb3/entity.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Sun Feb 4 00:08:32 EST 2007
Author: bstansberry at jboss.com
Date: 2007-02-04 00:08:32 -0500 (Sun, 04 Feb 2007)
New Revision: 60250
Added:
branches/Branch_4_2/ejb3/src/main/org/jboss/ejb3/entity/JBCCache.java
Modified:
branches/Branch_4_2/ejb3/src/main/org/jboss/ejb3/entity/TreeCacheProviderHook.java
Log:
Port EJBTHREE-798 fix to Branch_4_2
Copied: branches/Branch_4_2/ejb3/src/main/org/jboss/ejb3/entity/JBCCache.java (from rev 60074, branches/Branch_4_0/ejb3/src/main/org/jboss/ejb3/entity/JBCCache.java)
===================================================================
--- branches/Branch_4_2/ejb3/src/main/org/jboss/ejb3/entity/JBCCache.java (rev 0)
+++ branches/Branch_4_2/ejb3/src/main/org/jboss/ejb3/entity/JBCCache.java 2007-02-04 05:08:32 UTC (rev 60250)
@@ -0,0 +1,331 @@
+//$Id: TreeCache.java 9965 2006-05-30 18:00:28Z steve.ebersole at jboss.com $
+package org.jboss.ejb3.entity;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.cache.Cache;
+import org.hibernate.cache.CacheException;
+import org.hibernate.cache.StandardQueryCache;
+import org.hibernate.cache.UpdateTimestampsCache;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.config.Option;
+import org.jboss.cache.lock.TimeoutException;
+
+/**
+ * Subclass of the standard <code>org.hibernate.cache.TreeCache</code> used as
+ * a workaround until issues related to JBCLUSTER-150 are resolved in Hibernate.
+ *
+ * @author Gavin King
+ * @author Brian Stansberry
+ */
+public class JBCCache implements Cache {
+
+ private static final Log log = LogFactory.getLog(JBCCache.class);
+
+ private static final String ITEM = "item";
+
+ private org.jboss.cache.TreeCache cache;
+ private final String regionName;
+ private final Fqn regionFqn;
+ private final TransactionManager transactionManager;
+ private boolean localWritesOnly;
+
+ public JBCCache(org.jboss.cache.TreeCache cache, String regionName, TransactionManager transactionManager)
+ throws CacheException {
+ this.cache = cache;
+ this.regionName = regionName;
+ this.regionFqn = Fqn.fromString( regionName.replace( '.', '/' ) );
+ this.transactionManager = transactionManager;
+ if (cache.getUseRegionBasedMarshalling())
+ {
+ localWritesOnly = StandardQueryCache.class.getName().equals(regionName);
+
+ boolean fetchState = cache.getFetchInMemoryState();
+ try
+ {
+ // We don't want a state transfer for the StandardQueryCache,
+ // as it can include classes from multiple scoped classloaders
+ if (localWritesOnly)
+ cache.setFetchInMemoryState(false);
+
+ // We always activate
+ activateCacheRegion(regionFqn.toString());
+ }
+ finally
+ {
+ // Restore the normal state transfer setting
+ if (localWritesOnly)
+ cache.setFetchInMemoryState(fetchState);
+ }
+ }
+ else
+ {
+ log.debug("TreeCache is not configured for region based marshalling");
+ }
+ }
+
+ public Object get(Object key) throws CacheException {
+ Transaction tx = suspend();
+ try {
+ return read(key);
+ }
+ finally {
+ resume( tx );
+ }
+ }
+
+ public Object read(Object key) throws CacheException {
+ try {
+ return cache.get( new Fqn( regionFqn, key ), ITEM );
+ }
+ catch (Exception e) {
+ throw new CacheException(e);
+ }
+ }
+
+ public void update(Object key, Object value) throws CacheException {
+ try {
+ if (localWritesOnly) {
+ Option option = new Option();
+ option.setCacheModeLocal(true);
+ cache.put( new Fqn( regionFqn, key ), ITEM, value, option );
+ }
+ else {
+ cache.put( new Fqn( regionFqn, key ), ITEM, value );
+ }
+ }
+ catch (Exception e) {
+ throw new CacheException(e);
+ }
+ }
+
+ public void put(Object key, Object value) throws CacheException {
+ Transaction tx = suspend();
+ try {
+ if (localWritesOnly) {
+ Option option = new Option();
+ option.setCacheModeLocal(true);
+ // Overloaded method isn't available, so have to use InvocationContext
+ cache.getInvocationContext().setOptionOverrides(option);
+ try {
+ // do the failfast put outside the scope of the JTA txn
+ cache.putFailFast( new Fqn( regionFqn, key ), ITEM, value, 0 );
+ }
+ finally {
+ cache.getInvocationContext().setOptionOverrides(null);
+ }
+ }
+ else {
+ //do the failfast put outside the scope of the JTA txn
+ cache.putFailFast( new Fqn( regionFqn, key ), ITEM, value, 0 );
+ }
+ }
+ catch (TimeoutException te) {
+ //ignore!
+ log.debug("ignoring write lock acquisition failure");
+ }
+ catch (Exception e) {
+ throw new CacheException(e);
+ }
+ finally {
+ resume( tx );
+ }
+ }
+
+ private void resume(Transaction tx) {
+ try {
+ if (tx!=null) transactionManager.resume(tx);
+ }
+ catch (Exception e) {
+ throw new CacheException("Could not resume transaction", e);
+ }
+ }
+
+ private Transaction suspend() {
+ Transaction tx = null;
+ try {
+ if ( transactionManager!=null ) {
+ tx = transactionManager.suspend();
+ }
+ }
+ catch (SystemException se) {
+ throw new CacheException("Could not suspend transaction", se);
+ }
+ return tx;
+ }
+
+ public void remove(Object key) throws CacheException {
+ try {
+ if (localWritesOnly) {
+ Option option = new Option();
+ option.setCacheModeLocal(true);
+ cache.remove( new Fqn( regionFqn, key ), option );
+ }
+ else {
+ cache.remove( new Fqn( regionFqn, key ) );
+ }
+ }
+ catch (Exception e) {
+ throw new CacheException(e);
+ }
+ }
+
+ public void clear() throws CacheException {
+ try {
+ cache.remove( regionFqn );
+ }
+ catch (Exception e) {
+ throw new CacheException(e);
+ }
+ }
+
+ public void destroy() throws CacheException {
+ try {
+ // NOTE : evict() operates locally only (i.e., does not propogate
+ // to any other nodes in the potential cluster). This is
+ // exactly what is needed when we destroy() here; destroy() is used
+ // as part of the process of shutting down a SessionFactory; thus
+ // these removals should not be propogated
+ cache.evict( regionFqn );
+
+ if (cache.getUseRegionBasedMarshalling() && !isSharedClassLoaderRegion(regionName))
+ {
+ inactivateCacheRegion();
+ }
+ }
+ catch (CacheException e)
+ {
+ throw e;
+ }
+ catch( Exception e ) {
+ throw new CacheException( e );
+ }
+ }
+
+ public void lock(Object key) throws CacheException {
+ throw new UnsupportedOperationException( "TreeCache is a fully transactional cache" + regionName );
+ }
+
+ public void unlock(Object key) throws CacheException {
+ throw new UnsupportedOperationException( "TreeCache is a fully transactional cache: " + regionName );
+ }
+
+ public long nextTimestamp() {
+ return System.currentTimeMillis() / 100;
+ }
+
+ public int getTimeout() {
+ return 600; //60 seconds
+ }
+
+ public String getRegionName() {
+ return regionName;
+ }
+
+ public long getSizeInMemory() {
+ return -1;
+ }
+
+ public long getElementCountInMemory() {
+ try {
+ Set children = cache.getChildrenNames( regionFqn );
+ return children == null ? 0 : children.size();
+ }
+ catch (Exception e) {
+ throw new CacheException(e);
+ }
+ }
+
+ public long getElementCountOnDisk() {
+ return 0;
+ }
+
+ public Map toMap() {
+ try {
+ Map result = new HashMap();
+ Set childrenNames = cache.getChildrenNames( regionFqn );
+ if (childrenNames != null) {
+ Iterator iter = childrenNames.iterator();
+ while ( iter.hasNext() ) {
+ Object key = iter.next();
+ result.put(
+ key,
+ cache.get( new Fqn( regionFqn, key ), ITEM )
+ );
+ }
+ }
+ return result;
+ }
+ catch (Exception e) {
+ throw new CacheException(e);
+ }
+ }
+
+ public String toString() {
+ return "TreeCache(" + regionName + ')';
+ }
+
+ private boolean isSharedClassLoaderRegion(String regionName)
+ {
+ return (StandardQueryCache.class.getName().equals(regionName)
+ || UpdateTimestampsCache.class.getName().equals(regionName));
+ }
+
+ private void activateCacheRegion(String regionName) throws CacheException
+ {
+ String fqnString = regionFqn.toString();
+ // FIXME -- find a way that doesn't involve this API
+ if (cache.getMarshaller().isInactive(fqnString))
+ {
+ try
+ {
+ // Only register the classloader if it's not a shared region.
+ // If it's shared, no single classloader is valid
+ if (!isSharedClassLoaderRegion(regionName))
+ {
+ cache.registerClassLoader(fqnString, Thread.currentThread().getContextClassLoader());
+ }
+ cache.activateRegion(fqnString);
+ }
+ catch (Exception e)
+ {
+ throw new CacheException("Problem activating region " + regionName, e);
+ }
+ }
+ else
+ {
+ log.debug("activateCacheRegion(): Region " + fqnString + " is already active");
+ }
+ }
+
+ private void inactivateCacheRegion() throws CacheException
+ {
+ String fqnString = regionFqn.toString();
+ // FIXME -- find a way that doesn't involve this API
+ if (!cache.getMarshaller().isInactive(fqnString))
+ {
+ try
+ {
+ cache.inactivateRegion(fqnString);
+ cache.unregisterClassLoader(fqnString);
+ }
+ catch (Exception e)
+ {
+ throw new CacheException("Problem activating region " + fqnString, e);
+ }
+ }
+ else
+ {
+ log.debug("inactivateCacheRegion(): Region " + fqnString + " is already inactive");
+ }
+ }
+}
Modified: branches/Branch_4_2/ejb3/src/main/org/jboss/ejb3/entity/TreeCacheProviderHook.java
===================================================================
--- branches/Branch_4_2/ejb3/src/main/org/jboss/ejb3/entity/TreeCacheProviderHook.java 2007-02-04 05:07:36 UTC (rev 60249)
+++ branches/Branch_4_2/ejb3/src/main/org/jboss/ejb3/entity/TreeCacheProviderHook.java 2007-02-04 05:08:32 UTC (rev 60250)
@@ -23,9 +23,15 @@
import java.util.Properties;
+import javax.management.ObjectName;
+
import org.hibernate.cache.Cache;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.CacheProvider;
+import org.jboss.cache.TreeCacheMBean;
+import org.jboss.ejb3.tx.TxUtil;
+import org.jboss.mx.util.MBeanProxyExt;
+import org.jboss.mx.util.MBeanServerLocator;
/**
* Support for a standalone JBossCache (TreeCache) instance. The JBossCache is configured
@@ -36,8 +42,9 @@
*/
public class TreeCacheProviderHook implements CacheProvider
{
- private TransactionalCacheFactory cacheFactory;
+ private org.jboss.cache.TreeCache cache;
+
/**
* Construct and configure the Cache representation of a named cache region.
*
@@ -49,8 +56,7 @@
*/
public Cache buildCache(String regionName, Properties properties) throws CacheException
{
-// return new TreeCache(cache, regionName, TxUtil.getTransactionManager());
- return cacheFactory.buildCache(regionName, properties);
+ return new JBCCache(cache, regionName, TxUtil.getTransactionManager());
}
public boolean isMinimalPutsEnabledByDefault()
@@ -72,17 +78,16 @@
*/
public void start(Properties properties)
{
- cacheFactory = TransactionalCacheFactory.getFactory(properties);
-// try
-// {
-// ObjectName mbeanObjectName = new ObjectName((String) properties.get("hibernate.treecache.mbean.object_name"));
-// TreeCacheMBean mbean = (TreeCacheMBean) MBeanProxyExt.create(TreeCacheMBean.class, mbeanObjectName, MBeanServerLocator.locateJBoss());
-// cache = mbean.getInstance();
-// }
-// catch (Exception e)
-// {
-// throw new CacheException(e);
-// }
+ try
+ {
+ ObjectName mbeanObjectName = new ObjectName((String) properties.get("hibernate.treecache.mbean.object_name"));
+ TreeCacheMBean mbean = (TreeCacheMBean) MBeanProxyExt.create(TreeCacheMBean.class, mbeanObjectName, MBeanServerLocator.locateJBoss());
+ cache = mbean.getInstance();
+ }
+ catch (Exception e)
+ {
+ throw new CacheException(e);
+ }
}
public void stop()
More information about the jboss-cvs-commits
mailing list