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
00058
00059 protected static int maxtime = 5000;
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
00101 if (tx == null) {
00102 ihContext = null;
00103 } else {
00104 itContext = null;
00105 }
00106 }
00107
00108 public void waitmyturn(Transaction tx) {
00109
00110
00111 if (tx != null) {
00112
00113
00114
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
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
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
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
00182 if (passivation) {
00183
00184 if (TraceEjb.isDebugSwapper()) TraceEjb.swapper.log(BasicLevel.DEBUG, ident);
00185
00186
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
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
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
00218 }
00219
00220 public synchronized void notifyWriting(Transaction tx, JEntityContext bctx) {
00221 return;
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 }