[prev in list] [next in list] [prev in thread] [next in thread]
List: jboss-cvs-commits
Subject: [jboss-cvs] jboss/src/main/org/jboss/ejb/plugins EntitySynchronizationInterceptor.java TxInterceptor
From: Alexey Loubyansky <loubyansky () users ! sourceforge ! net>
Date: 2004-02-28 17:38:08
Message-ID: E1Ax8Pg-0005Rl-CW () sc8-pr-cvs1 ! sourceforge ! net
[Download RAW message or body]
User: loubyansky
Date: 04/02/28 09:38:08
Modified: src/main/org/jboss/ejb/plugins
EntitySynchronizationInterceptor.java
TxInterceptorCMT.java
Log:
merged from Branch_3_2
Revision Changes Path
1.80 +133 -74 \
jboss/src/main/org/jboss/ejb/plugins/EntitySynchronizationInterceptor.java
Index: EntitySynchronizationInterceptor.java
===================================================================
RCS file: /cvsroot/jboss/jboss/src/main/org/jboss/ejb/plugins/EntitySynchronizationInterceptor.java,v
retrieving revision 1.79
retrieving revision 1.80
diff -u -r1.79 -r1.80
--- EntitySynchronizationInterceptor.java 5 Oct 2003 17:41:55 -0000 1.79
+++ EntitySynchronizationInterceptor.java 28 Feb 2004 17:38:08 -0000 1.80
@@ -6,7 +6,6 @@
*/
package org.jboss.ejb.plugins;
-import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.ejb.EJBException;
@@ -85,9 +84,8 @@
ConfigurationMetaData configuration = \
container.getBeanMetaData().getContainerConfiguration(); commitOption = \
configuration.getCommitOption(); optionDRefreshRate = \
configuration.getOptionDRefreshRate();
-
}
- catch (Exception e)
+ catch(Exception e)
{
log.warn(e.getMessage());
}
@@ -105,7 +103,7 @@
vcrThread.start();
}
}
- catch (Exception e)
+ catch(Exception e)
{
vcrThread = null;
log.warn("problem starting valid contexts refresher thread", e);
@@ -114,7 +112,7 @@
public void stop()
{
- if (vcrThread != null)
+ if(vcrThread != null)
{
Thread temp = vcrThread;
vcrThread = null;
@@ -134,14 +132,14 @@
protected void register(EntityEnterpriseContext ctx, Transaction tx)
{
boolean trace = log.isTraceEnabled();
- if (trace)
+ if(trace)
log.trace("register, ctx=" + ctx + ", tx=" + tx);
EntityContainer ctxContainer = null;
try
{
- ctxContainer = (EntityContainer) ctx.getContainer();
- if (!ctx.hasTxSynchronization())
+ ctxContainer = (EntityContainer)ctx.getContainer();
+ if(!ctx.hasTxSynchronization())
{
// Create a new synchronization
Synchronization synch = createSynchronization(tx, ctx);
@@ -157,15 +155,15 @@
ctx.hasTxSynchronization(true);
}
//mark it dirty in global tx entity map if it is not read only
- if (!ctxContainer.isReadOnly())
+ if(!ctxContainer.isReadOnly())
{
EntityContainer.getGlobalTxEntityMap().associate(tx, ctx);
}
}
- catch (RollbackException e)
+ catch(RollbackException e)
{
// The state in the instance is to be discarded, we force a reload of \
state
- synchronized (ctx)
+ synchronized(ctx)
{
ctx.setValid(false);
ctx.hasTxSynchronization(false);
@@ -173,16 +171,16 @@
}
throw new EJBException(e);
}
- catch (Throwable t)
+ catch(Throwable t)
{
// If anything goes wrong with the association remove the ctx-tx \
association ctx.hasTxSynchronization(false);
- if (t instanceof RuntimeException)
- throw (RuntimeException) t;
- else if (t instanceof Error)
- throw (Error) t;
- else if (t instanceof Exception)
- throw new EJBException((Exception) t);
+ if(t instanceof RuntimeException)
+ throw (RuntimeException)t;
+ else if(t instanceof Error)
+ throw (Error)t;
+ else if(t instanceof Exception)
+ throw new EJBException((Exception)t);
else
throw new NestedRuntimeException(t);
}
@@ -190,20 +188,19 @@
public Object invokeHome(Invocation mi) throws Exception
{
-
- EntityEnterpriseContext ctx = (EntityEnterpriseContext) \
mi.getEnterpriseContext(); + EntityEnterpriseContext ctx = \
(EntityEnterpriseContext)mi.getEnterpriseContext(); Transaction tx = \
mi.getTransaction();
Object rtn = getNext().invokeHome(mi);
// An anonymous context was sent in, so if it has an id it is a real \
instance now
- if (ctx.getId() != null)
+ if(ctx.getId() != null)
{
// it doesn't need to be read, but it might have been changed from the db \
already. ctx.setValid(true);
- if (tx != null)
+ if(tx != null)
{
BeanLock lock = container.getLockManager().getLock(ctx.getCacheKey());
try
@@ -224,30 +221,51 @@
public Object invoke(Invocation mi) throws Exception
{
// We are going to work with the context a lot
- EntityEnterpriseContext ctx = (EntityEnterpriseContext) \
mi.getEnterpriseContext(); + EntityEnterpriseContext ctx = \
(EntityEnterpriseContext)mi.getEnterpriseContext();
// The Tx coming as part of the Method Invocation
Transaction tx = mi.getTransaction();
- if (log.isTraceEnabled())
+ if(log.isTraceEnabled())
log.trace("invoke called for ctx " + ctx + ", tx=" + tx);
- // Is my state valid?
- if (!ctx.isValid())
- {
- // If not tell the persistence manager to load the state
- container.getPersistenceManager().loadEntity(ctx);
+ // TODO: refactor it
+ Object pctx = ctx.getPersistenceContext();
+ if(pctx != null)
+ {
+ // CMP
+ // synchronization is needed for NotSupported transactions.
+ // In this case, there is no pessimistic locking and concurrent \
transactions can access + // persistence context. But on operations like \
load and store synchronization is required. + synchronized(pctx)
+ {
+ // Is my state valid?
+ if(!ctx.isValid())
+ {
+ // If not tell the persistence manager to load the state
+ container.getPersistenceManager().loadEntity(ctx);
- // Now the state is valid
- ctx.setValid(true);
+ // Now the state is valid
+ ctx.setValid(true);
+ }
+ }
+ }
+ else
+ {
+ // BMP
+ if(!ctx.isValid())
+ {
+ container.getPersistenceManager().loadEntity(ctx);
+ ctx.setValid(true);
+ }
}
// mark the context as read only if this is a readonly method and the \
context // was not already readonly
boolean didSetReadOnly = false;
- if (!ctx.isReadOnly() &&
- (container.isReadOnly() ||
- container.getBeanMetaData().isMethodReadOnly(mi.getMethod())))
+ if(!ctx.isReadOnly() &&
+ (container.isReadOnly() ||
+ container.getBeanMetaData().isMethodReadOnly(mi.getMethod())))
{
ctx.setReadOnly(true);
didSetReadOnly = true;
@@ -258,64 +276,105 @@
// Invocation with a running Transaction
try
{
- if (tx != null && tx.getStatus() != Status.STATUS_NO_TRANSACTION)
+ if(tx != null && tx.getStatus() != Status.STATUS_NO_TRANSACTION)
{
// readonly does not synchronize, lock or belong with transaction.
- if (!container.isReadOnly())
+ boolean isReadOnly = container.isReadOnly();
+ if(isReadOnly == false) ;
{
Method method = mi.getMethod();
- if (method == null ||
- \
!container.getBeanMetaData().isMethodReadOnly(method.getName())) + \
if(method != null) + isReadOnly = \
container.getBeanMetaData().isMethodReadOnly(method.getName()); + }
+ try
+ {
+ if(isReadOnly == false)
{
// register the wrapper with the transaction monitor (but only
// register once). The transaction demarcation will trigger the
// storage operations
register(ctx, tx);
}
- }
- //Invoke down the chain
- Object retVal = getNext().invoke(mi);
- // Register again as a finder in the middle of a method
- // will de-register this entity, and then the rest of the method can
- // change fields which will never be stored
- if (!container.isReadOnly())
- {
- Method method = mi.getMethod();
- if (method == null ||
- \
!container.getBeanMetaData().isMethodReadOnly(method.getName())) + \
//Invoke down the chain + Object retVal = getNext().invoke(mi);
+
+ // Register again as a finder in the middle of a method
+ // will de-register this entity, and then the rest of the method \
can + // change fields which will never be stored
+ if(isReadOnly == false)
{
// register the wrapper with the transaction monitor (but only
// register once). The transaction demarcation will trigger the
// storage operations
register(ctx, tx);
}
+
+ // return the return value
+ return retVal;
}
+ finally
+ {
+ // We were read-only and the context wasn't already synchronized, \
tidyup the cache + if(isReadOnly && ctx.hasTxSynchronization() == \
false) + {
+ switch(commitOption)
+ {
+ // Keep instance active, but invalidate state
+ case ConfigurationMetaData.B_COMMIT_OPTION:
+ // Invalidate state (there might be other points of entry)
+ ctx.setValid(false);
+ break;
- // return the return value
- return retVal;
+ // Invalidate everything AND Passivate instance
+ case ConfigurationMetaData.C_COMMIT_OPTION:
+ try
+ {
+ // FIXME: We cannot passivate here, because previous
+ // interceptors work with the context, in particular
+ // the re-entrance interceptor is doing lock counting
+ // Just remove it from the cache
+ if(ctx.getId() != null)
+ container.getInstanceCache().remove(ctx.getId());
+ }
+ catch(Exception e)
+ {
+ log.debug("Exception releasing context", e);
+ }
+ break;
+ }
+ }
+ }
}
else
{
// No tx
try
{
-
Object result = getNext().invoke(mi);
// Store after each invocation -- not on exception though, or \
removal // And skip reads too ("get" methods)
- if (ctx.getId() != null)
+ if(ctx.getId() != null && !container.isReadOnly())
{
- if (!container.isReadOnly())
+ if(pctx != null)
+ {
+ // for CMP NotSupported
+ synchronized(pctx)
+ {
+ container.storeEntity(ctx);
+ }
+ }
+ else
{
+ // BMP
container.storeEntity(ctx);
}
}
return result;
}
- catch (Exception e)
+ catch(Exception e)
{
// Exception - force reload on next call
ctx.setValid(false);
@@ -323,7 +382,7 @@
}
finally
{
- switch (commitOption)
+ switch(commitOption)
{
// Keep instance active, but invalidate state
case ConfigurationMetaData.B_COMMIT_OPTION:
@@ -342,10 +401,10 @@
// This is necessary because we have no lock, we
// don't want to return an instance to the pool that is
// being used
- if (ctx.getId() != null)
+ if(ctx.getId() != null)
container.getInstanceCache().release(ctx);
}
- catch (Exception e)
+ catch(Exception e)
{
log.debug("Exception releasing context", e);
}
@@ -357,7 +416,7 @@
finally
{
// if we marked the context as read only we need to reset it
- if (didSetReadOnly)
+ if(didSetReadOnly)
{
ctx.setReadOnly(false);
}
@@ -416,14 +475,14 @@
try
{
// If rolled back -> invalidate instance
- if (status == Status.STATUS_ROLLEDBACK)
+ if(status == Status.STATUS_ROLLEDBACK)
{
// remove from the cache
container.getInstanceCache().remove(ctx.getCacheKey());
}
else
{
- switch (commitOption)
+ switch(commitOption)
{
// Keep instance cached after tx commit
case ConfigurationMetaData.A_COMMIT_OPTION:
@@ -444,15 +503,15 @@
// We weren't removed, passivate
// Here we own the lock, so we don't try to passivate
// we just passivate
- if (ctx.getId() != null)
+ if(ctx.getId() != null)
{
container.getInstanceCache().remove(ctx.getId());
\
container.getPersistenceManager().passivateEntity(ctx);
- }
+ }
// If we get this far, we return to the pool
container.getInstancePool().free(ctx);
}
- catch (Exception e)
+ catch(Exception e)
{
log.debug("Exception releasing context", e);
}
@@ -462,11 +521,11 @@
}
finally
{
- if (trace)
+ if(trace)
log.trace("afterCompletion, clear tx for ctx=" + ctx + ", tx=" + \
tx); lock.endTransaction(tx);
- if (trace)
+ if(trace)
log.trace("afterCompletion, sent notify on TxLock for ctx=" + \
ctx); }
} // synchronized(lock)
@@ -491,9 +550,9 @@
public void run()
{
- while (vcrThread != null)
+ while(vcrThread != null)
{
- if (log.isTraceEnabled())
+ if(log.isTraceEnabled())
{
log.trace("Flushing the valid contexts");
}
@@ -502,15 +561,15 @@
{
Thread.sleep(refreshRate);
}
- catch (InterruptedException ignored)
+ catch(InterruptedException ignored)
{
}
- // Guard against NPE at shutdown
- if (container != null)
+ // Guard against NPE at shutdown
+ if(container != null)
{
- EntityCache cache = (EntityCache) container.getInstanceCache();
- if (cache != null)
+ EntityCache cache = (EntityCache)container.getInstanceCache();
+ if(cache != null)
cache.flush();
}
}
1.41 +12 -5 jboss/src/main/org/jboss/ejb/plugins/TxInterceptorCMT.java
Index: TxInterceptorCMT.java
===================================================================
RCS file: /cvsroot/jboss/jboss/src/main/org/jboss/ejb/plugins/TxInterceptorCMT.java,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -r1.40 -r1.41
--- TxInterceptorCMT.java 8 Jan 2004 00:32:47 -0000 1.40
+++ TxInterceptorCMT.java 28 Feb 2004 17:38:08 -0000 1.41
@@ -15,6 +15,7 @@
import org.jboss.tm.JBossTransactionRolledbackLocalException;
import org.jboss.util.NestedException;
import org.jboss.util.deadlock.ApplicationDeadlockException;
+import org.w3c.dom.Element;
import javax.ejb.EJBException;
import javax.ejb.TransactionRequiredLocalException;
@@ -28,13 +29,11 @@
import javax.transaction.TransactionRolledbackException;
import java.lang.reflect.Method;
import java.rmi.RemoteException;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.Iterator;
-
-import org.w3c.dom.Element;
+import java.util.ArrayList;
/**
* This interceptor handles transactions for CMT beans.
@@ -277,7 +276,15 @@
case MetaData.TX_NOT_SUPPORTED:
{
// Do not set a transaction on the thread even if in MI, just run
- return invokeNext(invocation, false);
+ try
+ {
+ invocation.setTransaction(null);
+ return invokeNext(invocation, false);
+ }
+ finally
+ {
+ invocation.setTransaction(oldTransaction);
+ }
}
case MetaData.TX_REQUIRED:
{
-------------------------------------------------------
SF.Net is sponsored by: Speed Start Your Linux Apps Now.
Build and deploy apps & Web services for Linux with
a free DVD software kit from IBM. Click Now!
http://ads.osdn.com/?ad_id=1356&alloc_id=3438&op=click
_______________________________________________
jboss-cvs-commits mailing list
jboss-cvs-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jboss-cvs-commits
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic