JEntitySwitchCRC.java

00001 
00026 package org.objectweb.jonas_ejb.container;
00027 
00028 import javax.ejb.EJBException;
00029 import javax.ejb.NoSuchObjectLocalException;
00030 import javax.ejb.TransactionRolledbackLocalException;
00031 import javax.transaction.Status;
00032 import javax.transaction.SystemException;
00033 import javax.transaction.Transaction;
00034 
00035 import org.objectweb.jonas_ejb.deployment.api.EntityDesc;
00036 
00037 import org.objectweb.util.monolog.api.BasicLevel;
00038 
00045 public class JEntitySwitchCRC extends JEntitySwitch {
00046 
00050     protected JEntityContext itContext = null;
00051 
00055     protected JEntityContext ihContext = null;
00056 
00057     // max time to wait when in a transaction, before checking if
00058     // transaction has been set rollback only (deadlock detection)
00059     protected static int maxtime = 5000; // 5 sec.
00060 
00065     public JEntitySwitchCRC() {
00066         lockpolicy = EntityDesc.LOCK_CONTAINER_READ_COMMITTED;
00067         txUpdates = true;
00068     }
00069 
00070     protected void initpolicy(JEntityFactory bf) {
00071         lazyregister = false;
00072     }
00073 
00074     protected JEntityContext getContext4Tx(Transaction tx) {
00075         JEntityContext ctx = null;
00076         if (tx == null) {
00077             ctx = ihContext;
00078         } else {
00079             ctx = itContext;
00080         }
00081         return ctx;
00082     }
00083 
00088     protected void setContext4Tx(Transaction tx, JEntityContext ctx) {
00089         if (tx == null) {
00090             ihContext = ctx;
00091         } else {
00092             itContext = ctx;
00093         }
00094     }
00095 
00099     protected void removeContext4Tx(Transaction tx) {
00100         // free this Context
00101         if (tx == null) {
00102             ihContext = null;
00103         } else {
00104             itContext = null;
00105         }
00106     }
00107 
00108     public void waitmyturn(Transaction tx) {
00109 
00110         // Synchronization.
00111         if (tx != null) {
00112             // Must wait in case of TX or if instance has been modified outside
00113             // transaction.
00114             // Don't wait transactions if 1 instance per transaction.
00115             int waitcount = 0;
00116             while (runningtx != null && !tx.equals(runningtx)) {
00117                 if (TraceEjb.isDebugSynchro())
00118                         TraceEjb.synchro.log(BasicLevel.DEBUG, ident + "mapICtx IT: WAIT end IT");
00119                 // deadlock detection
00120                 blockedtx = tx;
00121                 if (waitcount++ > 1 && bf.isBlocked(runningtx) && bf.isBlocking(tx)) {
00122                     try {
00123                         tx.setRollbackOnly();
00124                     } catch (SystemException e) {
00125                         TraceEjb.logger.log(BasicLevel.ERROR, ident
00126                                 + "getICtx IT: unexpected exception setting rollbackonly");
00127                     }
00128                     TraceEjb.logger.log(BasicLevel.WARN, ident + "getICtx IT: transaction rolled back");
00129                     throw new TransactionRolledbackLocalException("possible deadlock");
00130                 }
00131                 waiters++;
00132                 try {
00133                     wait(maxtime);
00134                     if (TraceEjb.isDebugSynchro())
00135                             TraceEjb.synchro.log(BasicLevel.DEBUG, ident + "mapICtx IT: NOTIFIED");
00136                 } catch (InterruptedException e) {
00137                     if (TraceEjb.isDebugSynchro())
00138                             TraceEjb.synchro.log(BasicLevel.DEBUG, ident + "mapICtx IT: INTERRUPTED");
00139                 } catch (Exception e) {
00140                     throw new EJBException("JEntitySwitch synchronization pb", e);
00141                 } finally {
00142                     waiters--;
00143                     blockedtx = null;
00144                 }
00145                 // If transaction has been rolledback or set rollback only, give up.
00146                 int status = Status.STATUS_ROLLEDBACK;
00147                 try {
00148                     status = tx.getStatus();
00149                 } catch (SystemException e) {
00150                     TraceEjb.logger.log(BasicLevel.ERROR, ident
00151                             + "getICtx IT: unexpected exception getting transaction status");
00152                 }
00153                 switch (status) {
00154                 case Status.STATUS_MARKED_ROLLBACK:
00155                 case Status.STATUS_ROLLEDBACK:
00156                 case Status.STATUS_ROLLING_BACK:
00157                     TraceEjb.logger.log(BasicLevel.WARN, ident + "getICtx IT: transaction rolled back");
00158                     throw new TransactionRolledbackLocalException("rollback occured while waiting");
00159                 }
00160             }
00161         }
00162     }
00163 
00169     public synchronized boolean passivateIH(boolean passivation) {
00170 
00171         // If already passivated, look if we can destroy the objects
00172         if (ihContext == null && itContext == null) {
00173             if (inactivityTimeout > 0 && 
00174                 System.currentTimeMillis() - timestamp > inactivityTimeout) {
00175                 TraceEjb.context.log(BasicLevel.DEBUG, "discard object on timeout");
00176                 discardContext(null, true, false);
00177             }
00178             return true;
00179         }
00180 
00181         // passivate this instance if required.
00182         if (passivation) {
00183 
00184             if (TraceEjb.isDebugSwapper()) TraceEjb.swapper.log(BasicLevel.DEBUG, ident);
00185 
00186             // Instance used when no transaction.
00187             JEntityContext jec = ihContext;
00188             if (jec != null) {
00189                 if (TraceEjb.isDebugContext()) TraceEjb.context.log(BasicLevel.DEBUG, "passivated: " + jec);
00190                 jec.passivate();
00191                 bf.releaseJContext(jec);
00192                 ihContext = null;
00193             }
00194             // Instance used for transactions
00195             jec = itContext;
00196             if (jec != null && runningtx == null) {
00197                 if (TraceEjb.isDebugContext()) TraceEjb.context.log(BasicLevel.DEBUG, "passivated: " + jec);
00198                 jec.passivate();
00199                 bf.releaseJContext(jec);
00200                 itContext = null;
00201             }
00202 
00203             // If passivation done, set the timestamp
00204             if (ihContext == null && itContext == null) {
00205                 timestamp = System.currentTimeMillis();
00206             }
00207 
00208             if (waiters > 0) {
00209                 TraceEjb.synchro.log(BasicLevel.DEBUG, ident + " notify");
00210                 notifyAll();
00211             }
00212         }
00213         return true;
00214     }
00215 
00216     public synchronized void endIH() {
00217         // Not used.
00218     }
00219 
00220     public synchronized void notifyWriting(Transaction tx, JEntityContext bctx) {
00221         return; // NEVER
00222     }
00223 
00229     public int getState() {
00230         if (ihContext != null) {
00231             if (ihContext.isMarkedRemoved()) {
00232                 return 4;
00233             } else {
00234                 if (inDirtyList) {
00235                     return 1;
00236                 } else {
00237                     if (itContext == null) {
00238                         return 2;
00239                     }
00240                 }
00241             }
00242         }
00243         if (itContext != null) {
00244             if (itContext.isMarkedRemoved()) {
00245                 return 4;
00246             } else {
00247                 if (runningtx != null) {
00248                     return 0;
00249                 } else {
00250                     return 2;
00251                 }
00252             }
00253         }
00254         return 3;
00255     }
00256 
00257 }

Generated on Tue Feb 15 15:05:37 2005 for JOnAS by  doxygen 1.3.9.1