User: mnf999
Date: 01/08/01 11:48:06
Modified: src/main/org/jboss/ejb/plugins
StatefulSessionInstanceInterceptor.java
Log:
Bill's Stateful int with externalized bean this could be moved to a full interceptor
like the entity
Revision Changes Path
1.20 +140 -94
jboss/src/main/org/jboss/ejb/plugins/StatefulSessionInstanceInterceptor.java
Index: StatefulSessionInstanceInterceptor.java
===================================================================
RCS file:
/cvsroot/jboss/jboss/src/main/org/jboss/ejb/plugins/StatefulSessionInstanceInterceptor.java,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- StatefulSessionInstanceInterceptor.java 2001/07/20 20:07:15 1.19
+++ StatefulSessionInstanceInterceptor.java 2001/08/01 18:48:06 1.20
@@ -20,6 +20,8 @@
import org.apache.log4j.Category;
+import org.jboss.ejb.BeanLock;
+import org.jboss.ejb.BeanLockManager;
import org.jboss.ejb.Container;
import org.jboss.ejb.InstanceCache;
import org.jboss.ejb.InstancePool;
@@ -28,20 +30,24 @@
import org.jboss.ejb.EnterpriseContext;
import org.jboss.ejb.MethodInvocation;
import org.jboss.metadata.SessionMetaData;
-import org.jboss.util.Sync;
/**
* This container acquires the given instance.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Rickard �berg</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
- * @version $Revision: 1.19 $
+ * @author <a href="mailto:[EMAIL PROTECTED]">Bill Burke</a>
+ * @version $Revision: 1.20 $
*
* <p><b>Revisions:</b>
* <p><b>20010704 marcf</b>
* <ul>
* <li>- Moved to new synchronization
* </ul>
+ * <p><b>20010726 billb</b>
+ * <ul>
+ * <li>- externalized bean locking in separate object BeanLock
+ * </ul>
*/
public class StatefulSessionInstanceInterceptor
extends AbstractInterceptor
@@ -131,10 +137,10 @@
}
}
- private void register(EnterpriseContext ctx, Transaction tx)
+ private void register(EnterpriseContext ctx, Transaction tx, BeanLock lock)
{
// Create a new synchronization
- InstanceSynchronization synch = new InstanceSynchronization(tx, ctx);
+ InstanceSynchronization synch = new InstanceSynchronization(tx, ctx, lock);
try {
// OSH: An extra check to avoid warning.
@@ -146,7 +152,17 @@
}
// We want to be notified when the transaction commits
- tx.registerSynchronization(synch);
+ try
+ {
+ tx.registerSynchronization(synch);
+ }
+ catch (Exception ex)
+ {
+ // synch adds a reference to the lock, so we must release the ref
+ // because afterCompletion will never get called.
+ getContainer().getLockManager().removeLockRef(lock.getId());
+ throw ex;
+ }
// EJB 1.1, 6.5.3
synch.afterBegin();
@@ -167,97 +183,115 @@
(AbstractInstanceCache)container.getInstanceCache();
Object id = mi.getId();
EnterpriseContext ctx = null;
-
- // Get context
- ctx = container.getInstanceCache().get(mi.getId());
- synchronized(ctx)
+ BeanLock lock = (BeanLock)container.getLockManager().getLock(id);
+ try
{
-
- // Associate it with the method invocation
- mi.setEnterpriseContext(ctx);
-
- // BMT beans will lock and replace tx no matter what, CMT do work on
transaction
- if (!((SessionMetaData)container.getBeanMetaData()).isBeanManagedTx()) {
+ lock.sync(); // synchronized(ctx)
+ try // lock.sync
+ {
+ // Get context
+ ctx = container.getInstanceCache().get(mi.getId());
+ // Associate it with the method invocation
+ mi.setEnterpriseContext(ctx);
+
+ // BMT beans will lock and replace tx no matter what, CMT do work on
transaction
+ if (!((SessionMetaData)container.getBeanMetaData()).isBeanManagedTx()) {
- // Do we have a running transaction with the context
- if (ctx.getTransaction() != null &&
- // And are we trying to enter with another transaction
- !ctx.getTransaction().equals(mi.getTransaction()))
- {
- // Calls must be in the same transaction
- throw new RemoteException("Application Error: tried to enter
Stateful bean with different transaction context");
- }
+ // Do we have a running transaction with the context
+ if (ctx.getTransaction() != null &&
+ // And are we trying to enter with another transaction
+ !ctx.getTransaction().equals(mi.getTransaction()))
+ {
+ // Calls must be in the same transaction
+ throw new RemoteException("Application Error: tried to enter
Stateful bean with different transaction context");
+ }
- //If the instance will participate in a new transaction we register a
sync for it
- if (ctx.getTransaction() == null && mi.getTransaction() != null) {
- register(ctx, mi.getTransaction());
+ //If the instance will participate in a new transaction we register
a sync for it
+ if (ctx.getTransaction() == null && mi.getTransaction() != null) {
+ register(ctx, mi.getTransaction(), lock);
+ }
}
- }
- if (!ctx.isLocked()){
-
- //take it!
- ctx.lock();
- } else
- {
- if (!isCallAllowed(mi))
+ if (!ctx.isLocked())
{
- // Calls must be in the same transaction
- throw new RemoteException("Application Error: no concurrent calls on
stateful beans");
- }
+
+ //take it!
+ ctx.lock();
+ }
else
{
- ctx.lock();
+ if (!isCallAllowed(mi))
+ {
+ // Concurent calls are not allowed
+ throw new RemoteException("Application Error: no concurrent calls
on stateful beans");
+ }
+ else
+ {
+ ctx.lock();
+ }
}
}
- }
+ finally
+ {
+ lock.releaseSync();
+ }
- try
- {
- // Invoke through interceptors
- return getNext().invoke(mi);
- } catch (RemoteException e)
- {
- // Discard instance
- container.getInstanceCache().remove(mi.getId());
- ctx = null;
+ try
+ {
+ // Invoke through interceptors
+ return getNext().invoke(mi);
+ } catch (RemoteException e)
+ {
+ // Discard instance
+ container.getInstanceCache().remove(mi.getId());
+ ctx = null;
- throw e;
- } catch (RuntimeException e)
- {
- // Discard instance
- container.getInstanceCache().remove(mi.getId());
- ctx = null;
+ throw e;
+ } catch (RuntimeException e)
+ {
+ // Discard instance
+ container.getInstanceCache().remove(mi.getId());
+ ctx = null;
- throw e;
- } catch (Error e)
- {
- // Discard instance
- container.getInstanceCache().remove(mi.getId());
- ctx = null;
+ throw e;
+ } catch (Error e)
+ {
+ // Discard instance
+ container.getInstanceCache().remove(mi.getId());
+ ctx = null;
- throw e;
- } finally
- {
- if (ctx != null)
+ throw e;
+ } finally
{
- // Still a valid instance
- synchronized(ctx)
+ if (ctx != null)
{
+ // Still a valid instance
+ lock.sync(); // synchronized(ctx)
+ try
+ {
- // release it
- ctx.unlock();
+ // release it
+ ctx.unlock();
- // if removed, remove from cache
- if (ctx.getId() == null)
+ // if removed, remove from cache
+ if (ctx.getId() == null)
+ {
+ // Remove from cache
+ container.getInstanceCache().remove(mi.getId());
+ }
+ }
+ finally
{
- // Remove from cache
- container.getInstanceCache().remove(mi.getId());
+ lock.releaseSync();
}
}
}
}
+ finally
+ {
+ container.getLockManager().removeLockRef(lock.getId());
+ }
}
private boolean isCallAllowed(MethodInvocation mi)
@@ -296,14 +330,17 @@
private Method afterBegin;
private Method beforeCompletion;
private Method afterCompletion;
+ private BeanLock lock;
/**
* Create a new instance synchronization instance.
*/
- InstanceSynchronization(Transaction tx, EnterpriseContext ctx)
+ InstanceSynchronization(Transaction tx, EnterpriseContext ctx, BeanLock lock)
{
this.tx = tx;
this.ctx = ctx;
+ this.lock = lock;
+ this.lock.addRef();
// Let's compute it now, to speed things up we could
notifySession = (ctx.getInstance() instanceof
javax.ejb.SessionSynchronization);
@@ -363,29 +400,38 @@
{
// DEBUG log.debug("afterCompletion called");
- // finish the transaction association
- ctx.setTransaction(null);
-
- // unlock this context
- ctx.unlock();
-
- if (notifySession) {
-
- try {
-
- if (status == Status.STATUS_COMMITTED) {
- afterCompletion.invoke(ctx.getInstance(),
- new Object[] { Boolean.TRUE });
+ lock.sync();
+ try
+ {
+ // finish the transaction association
+ ctx.setTransaction(null);
+
+ // unlock this context
+ ctx.unlock();
+
+ if (notifySession) {
+
+ try {
+
+ if (status == Status.STATUS_COMMITTED) {
+ afterCompletion.invoke(ctx.getInstance(),
+ new Object[] { Boolean.TRUE });
+ }
+ else {
+ afterCompletion.invoke(ctx.getInstance(),
+ new Object[] { Boolean.FALSE });
+ }
}
- else {
- afterCompletion.invoke(ctx.getInstance(),
- new Object[] { Boolean.FALSE });
+ catch (Exception e) {
+ log.error("failed to invoke afterCompletion", e);
}
- }
- catch (Exception e) {
- log.error("failed to invoke afterCompletion", e);
- }
- }
+ }
+ }
+ finally
+ {
+ lock.releaseSync();
+ container.getLockManager().removeLockRef(lock.getId());
+ }
}
}
}
_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/jboss-development