User: patriot1burke
Date: 01/08/09 13:28:56
Added: src/main/org/jboss/ejb/plugins
EntityMultiInstanceSynchronizationInterceptor.java
EntityMultiInstanceInterceptor.java
Log:
Entity instance per transaction
Revision Changes Path
1.1
jboss/src/main/org/jboss/ejb/plugins/EntityMultiInstanceSynchronizationInterceptor.java
Index: EntityMultiInstanceSynchronizationInterceptor.java
===================================================================
/**
* JBoss, the OpenSource J2EE webOS
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb.plugins;
import java.lang.reflect.Method;
import java.rmi.RemoteException;
import java.rmi.ServerException;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.HashSet;
import javax.ejb.EJBObject;
import javax.ejb.CreateException;
import javax.ejb.EJBException;
import javax.ejb.NoSuchEntityException;
import javax.ejb.RemoveException;
import javax.ejb.EntityBean;
import javax.transaction.Status;
import javax.transaction.Synchronization;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;
import org.jboss.ejb.BeanLock;
import org.jboss.ejb.BeanLockManager;
import org.jboss.ejb.Container;
import org.jboss.ejb.EntityContainer;
import org.jboss.ejb.EntityPersistenceManager;
import org.jboss.ejb.EntityEnterpriseContext;
import org.jboss.ejb.EnterpriseContext;
import org.jboss.ejb.InstanceCache;
import org.jboss.ejb.InstancePool;
import org.jboss.ejb.MethodInvocation;
import org.jboss.metadata.ConfigurationMetaData;
import org.jboss.logging.log4j.JBossCategory;
import org.jboss.util.Sync;
/**
* The role of this interceptor is to synchronize the state of the cache with
* the underlying storage. It does this with the ejbLoad and ejbStore
* semantics of the EJB specification. In the presence of a transaction this
* is triggered by transaction demarcation. It registers a callback with the
* underlying transaction monitor through the JTA interfaces. If there is no
* transaction the policy is to store state upon returning from invocation.
* The synchronization polices A,B,C of the specification are taken care of
* here.
*
* <p><b>WARNING: critical code</b>, get approval from senior developers
* before changing.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Bill Burke</a>
* @version $Revision: 1.1 $
*
* <p><b>Revisions:</b><br>
* <p><b>2001/08/08: billb</b>
* <ol>
* <li>Initial revision
* </ol>
*/
public class EntityMultiInstanceSynchronizationInterceptor
extends EntitySynchronizationInterceptor
{
public void init()
throws Exception
{
super.init();
if (container.getInstancePool() instanceof EntityInstancePool)
{
((EntityInstancePool)container.getInstancePool()).setReclaim(true);
}
}
protected Synchronization createSynchronization(Transaction tx,
EntityEnterpriseContext ctx)
{
return new MultiInstanceSynchronization(tx, ctx);
}
// Protected ----------------------------------------------------
// Inner classes -------------------------------------------------
protected class MultiInstanceSynchronization extends
EntitySynchronizationInterceptor.InstanceSynchronization
{
/**
* The transaction we follow.
*/
private Transaction tx;
/**
* The context we manage.
*/
private EntityEnterpriseContext ctx;
/**
* The context lock
*/
private BeanLock lock;
/**
* Create a new instance synchronization instance.
*/
MultiInstanceSynchronization(Transaction tx, EntityEnterpriseContext ctx)
{
super(tx, ctx);
}
// Synchronization implementation -----------------------------
public void afterCompletion(int status)
{
boolean trace = log.isTraceEnabled();
// This is an independent point of entry. We need to make sure the
// thread is associated with the right context class loader
ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(container.getClassLoader());
lock.sync();
try
{
try
{
// If rolled back -> invalidate instance
if (status != Status.STATUS_ROLLEDBACK)
{
switch (commitOption)
{
// Keep instance cached after tx commit
case ConfigurationMetaData.A_COMMIT_OPTION:
throw new IllegalStateException("Commit option A not allowed
with this Interceptor");
// Keep instance active, but invalidate state
case ConfigurationMetaData.B_COMMIT_OPTION:
break;
// Invalidate everything AND Passivate instance
case ConfigurationMetaData.C_COMMIT_OPTION:
break;
case ConfigurationMetaData.D_COMMIT_OPTION:
throw new IllegalStateException("Commit option A not allowed
with this Interceptor");
}
}
try
{
container.getPersistenceManager().passivateEntity(ctx);
}
catch (Exception ignored) {}
container.getInstancePool().free(ctx);
}
finally
{
if( trace )
log.trace("afterCompletion, clear tx for ctx="+ctx+", tx="+tx);
lock.endTransaction(tx);
if( trace )
log.trace("afterCompletion, sent notify on TxLock for ctx="+ctx);
}
} // synchronized(lock)
finally
{
lock.releaseSync();
container.getLockManager().removeLockRef(lock.getId());
Thread.currentThread().setContextClassLoader(oldCl);
}
}
}
}
1.1
jboss/src/main/org/jboss/ejb/plugins/EntityMultiInstanceInterceptor.java
Index: EntityMultiInstanceInterceptor.java
===================================================================
/*
* JBoss, the OpenSource J2EE webOS
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb.plugins;
import java.lang.reflect.Method;
import java.rmi.RemoteException;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;
import javax.ejb.EJBObject;
import javax.ejb.CreateException;
import javax.ejb.EJBException;
import javax.ejb.NoSuchEntityException;
import javax.ejb.RemoveException;
import javax.ejb.EntityBean;
import javax.transaction.Status;
import javax.transaction.Synchronization;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;
import org.jboss.ejb.Container;
import org.jboss.ejb.BeanLock;
import org.jboss.ejb.BeanLockManager;
import org.jboss.ejb.EntityContainer;
import org.jboss.ejb.EntityPersistenceManager;
import org.jboss.ejb.EntityEnterpriseContext;
import org.jboss.ejb.EnterpriseContext;
import org.jboss.ejb.InstanceCache;
import org.jboss.ejb.InstancePool;
import org.jboss.ejb.MethodInvocation;
import org.jboss.ejb.CacheKey;
import org.jboss.logging.log4j.JBossCategory;
import org.jboss.metadata.EntityMetaData;
import org.jboss.tm.TxManager;
/**
* The instance interceptors role is to acquire a context representing
* the target object from the cache.
*
*
* @author <a href="mailto:[EMAIL PROTECTED]">Bill Burke</a>
* @version $Revision: 1.1 $
*
* <p><b>Revisions:</b><br>
* <p><b>2001/08/08: billb</b>
* <ol>
* <li>Initial Revision
* </ol>
*/
public class EntityMultiInstanceInterceptor
extends AbstractInterceptor
{
// Constants -----------------------------------------------------
// Attributes ----------------------------------------------------
protected EntityContainer container;
// Static --------------------------------------------------------
/** Use a JBoss custom log4j category for trace level logging */
static JBossCategory log = (JBossCategory)
JBossCategory.getInstance(EntityMultiInstanceInterceptor.class);
// Constructors --------------------------------------------------
// Public --------------------------------------------------------
public void setContainer(Container container)
{
this.container = (EntityContainer)container;
}
public Container getContainer()
{
return container;
}
// Interceptor implementation --------------------------------------
public Object invokeHome(MethodInvocation mi)
throws Exception
{
// Get context
EntityEnterpriseContext ctx =
(EntityEnterpriseContext)((EntityContainer)getContainer()).getInstancePool().get();
// Pass it to the method invocation
mi.setEnterpriseContext(ctx);
// Give it the transaction
ctx.setTransaction(mi.getTransaction());
// Invoke through interceptors
return getNext().invokeHome(mi);
}
public Object invoke(MethodInvocation mi)
throws Exception
{
// The key
CacheKey key = (CacheKey) mi.getId();
EntityEnterpriseContext ctx = null;
if (mi.getTransaction() != null)
{
ctx = container.getTxEntityMap().getCtx(mi.getTransaction(), key);
}
if (ctx == null)
{
ctx = (EntityEnterpriseContext)container.getInstancePool().get();
ctx.setCacheKey(key);
ctx.setId(key.getId());
container.getPersistenceManager().activateEntity(ctx);
}
boolean trace = log.isTraceEnabled();
if( trace ) log.trace("Begin invoke, key="+key);
// Associate transaction, in the new design the lock already has the
transaction from the
// previous interceptor
ctx.setTransaction(mi.getTransaction());
// Set context on the method invocation
mi.setEnterpriseContext(ctx);
return getNext().invoke(mi);
}
}
_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/jboss-development