KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jonas_ejb > container > JEntitySwitchCRC


1 /**
2  * JOnAS: Java(TM) Open Application Server
3  * Copyright (C) 1999 Bull S.A.
4  * Contact: jonas-team@objectweb.org
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  * USA
20  *
21  * --------------------------------------------------------------------------
22  * $Id: JEntitySwitchCRC.java,v 1.20 2005/04/28 16:52:59 benoitf Exp $
23  * --------------------------------------------------------------------------
24  */

25
26 package org.objectweb.jonas_ejb.container;
27
28 import javax.ejb.EJBException JavaDoc;
29 import javax.ejb.NoSuchObjectLocalException JavaDoc;
30 import javax.ejb.TransactionRolledbackLocalException JavaDoc;
31 import javax.transaction.Status JavaDoc;
32 import javax.transaction.SystemException JavaDoc;
33 import javax.transaction.Transaction JavaDoc;
34
35 import org.objectweb.jonas_ejb.deployment.api.EntityDesc;
36
37 import org.objectweb.util.monolog.api.BasicLevel;
38
39 /**
40  * Container read committed lock policy.
41  * transactions are serialized by the container.
42  * Accesses outside transaction read committed state.
43  * @author Philippe Durieux
44  */

45 public class JEntitySwitchCRC extends JEntitySwitch {
46
47     /**
48      * EntityContext for transacted requests
49      */

50     protected JEntityContext itContext = null;
51
52     /**
53      * EntityContext for non-transacted requests
54      */

55     protected JEntityContext ihContext = null;
56
57     // max time to wait when in a transaction, before checking if
58
// transaction has been set rollback only (deadlock detection)
59
protected static int maxtime = 5000; // 5 sec.
60

61     /**
62      * empty constructor. Object is initialized via init() because it is
63      * implemented differently according to jorm mappers.
64      */

65     public JEntitySwitchCRC() {
66         lockpolicy = EntityDesc.LOCK_CONTAINER_READ_COMMITTED;
67         txUpdates = true;
68     }
69
70     protected void initpolicy(JEntityFactory bf) {
71         lazyregister = false;
72     }
73
74     protected JEntityContext getContext4Tx(Transaction JavaDoc tx) {
75         JEntityContext ctx = null;
76         if (tx == null) {
77             ctx = ihContext;
78         } else {
79             ctx = itContext;
80         }
81         return ctx;
82     }
83
84     /**
85      * @param tx The Transaction
86      * @param the JEntityContext used for this tx
87      */

88     protected void setContext4Tx(Transaction JavaDoc tx, JEntityContext ctx) {
89         if (tx == null) {
90             ihContext = ctx;
91         } else {
92             itContext = ctx;
93         }
94     }
95
96     /**
97      *
98      */

99     protected void removeContext4Tx(Transaction JavaDoc tx) {
100         // free this Context
101
if (tx == null) {
102             ihContext = null;
103         } else {
104             itContext = null;
105         }
106     }
107
108     public void waitmyturn(Transaction JavaDoc tx) {
109
110         // Synchronization.
111
if (tx != null) {
112             // Must wait in case of TX or if instance has been modified outside
113
// transaction.
114
// Don't wait transactions if 1 instance per transaction.
115
int waitcount = 0;
116             while (runningtx != null && !tx.equals(runningtx)) {
117                 if (TraceEjb.isDebugSynchro()) {
118                         TraceEjb.synchro.log(BasicLevel.DEBUG, ident + "mapICtx IT: WAIT end IT");
119                 }
120                 // deadlock detection
121
blockedtx = tx;
122                 if (waitcount++ > 1 && bf.isBlocked(runningtx) && bf.isBlocking(tx)) {
123                     try {
124                         tx.setRollbackOnly();
125                     } catch (SystemException JavaDoc e) {
126                         TraceEjb.logger.log(BasicLevel.ERROR, ident
127                                 + "getICtx IT: unexpected exception setting rollbackonly", e);
128                     }
129                     TraceEjb.logger.log(BasicLevel.WARN, ident + "getICtx IT: transaction rolled back");
130                     throw new TransactionRolledbackLocalException JavaDoc("possible deadlock");
131                 }
132                 waiters++;
133                 try {
134                     wait(maxtime);
135                     if (TraceEjb.isDebugSynchro()) {
136                             TraceEjb.synchro.log(BasicLevel.DEBUG, ident + "mapICtx IT: NOTIFIED");
137                     }
138                 } catch (InterruptedException JavaDoc e) {
139                     if (TraceEjb.isDebugSynchro()) {
140                             TraceEjb.synchro.log(BasicLevel.DEBUG, ident + "mapICtx IT: INTERRUPTED", e);
141                     }
142                 } catch (Exception JavaDoc e) {
143                     throw new EJBException JavaDoc("JEntitySwitch synchronization pb", e);
144                 } finally {
145                     waiters--;
146                     blockedtx = null;
147                 }
148                 // If transaction has been rolledback or set rollback only, give up.
149
int status = Status.STATUS_ROLLEDBACK;
150                 try {
151                     status = tx.getStatus();
152                 } catch (SystemException JavaDoc e) {
153                     TraceEjb.logger.log(BasicLevel.ERROR, ident
154                             + "getICtx IT: unexpected exception getting transaction status", e);
155                 }
156                 switch (status) {
157                 case Status.STATUS_MARKED_ROLLBACK:
158                 case Status.STATUS_ROLLEDBACK:
159                 case Status.STATUS_ROLLING_BACK:
160                     if (TraceEjb.isVerbose()) {
161                         TraceEjb.logger.log(BasicLevel.WARN, ident + "getICtx IT: transaction rolled back");
162                     }
163                     throw new TransactionRolledbackLocalException JavaDoc("rollback occured while waiting");
164                 }
165             }
166         }
167     }
168
169     /**
170      * try to passivate IH (called from swapper)
171      * @param passivation false if only store bean state.
172      * @return false if instance still in memory (busy for example)
173      */

174     public synchronized boolean passivateIH(boolean passivation) {
175
176         // If already passivated, look if we can destroy the objects
177
if (ihContext == null && itContext == null) {
178             if (inactivityTimeout > 0 &&
179                 System.currentTimeMillis() - timestamp > inactivityTimeout) {
180                 if (TraceEjb.isDebugContext()) {
181                     TraceEjb.context.log(BasicLevel.DEBUG, "discard object on timeout");
182                 }
183                 discardContext(null, true, false);
184             }
185             return true;
186         }
187
188         // passivate this instance if required.
189
if (passivation) {
190
191             if (TraceEjb.isDebugSwapper()) {
192                 TraceEjb.swapper.log(BasicLevel.DEBUG, ident);
193             }
194
195             // Instance used when no transaction.
196
JEntityContext jec = ihContext;
197             if (jec != null) {
198                 if (TraceEjb.isDebugContext()) {
199                     TraceEjb.context.log(BasicLevel.DEBUG, "passivated: " + jec);
200                 }
201                 jec.passivate();
202                 bf.releaseJContext(jec);
203                 ihContext = null;
204             }
205             // Instance used for transactions
206
jec = itContext;
207             if (jec != null && runningtx == null) {
208                 if (TraceEjb.isDebugContext()) {
209                     TraceEjb.context.log(BasicLevel.DEBUG, "passivated: " + jec);
210                 }
211                 jec.passivate();
212                 bf.releaseJContext(jec);
213                 itContext = null;
214             }
215
216             // If passivation done, set the timestamp
217
if (ihContext == null && itContext == null) {
218                 timestamp = System.currentTimeMillis();
219             }
220
221             if (waiters > 0) {
222                 if (TraceEjb.isDebugSynchro()) {
223                     TraceEjb.synchro.log(BasicLevel.DEBUG, ident + " notify");
224                 }
225                 notifyAll();
226             }
227         }
228         return true;
229     }
230
231     public synchronized void endIH() {
232         // Not used.
233
}
234
235     public synchronized void notifyWriting(Transaction JavaDoc tx, JEntityContext bctx) {
236         return; // NEVER
237
}
238
239     /**
240      * @return State of this instance. State values are 0=in-tx, 1=out-tx, 2=idle,
241      * 3=passive, 4=removed. we don't synchronize this method to avoid
242      * jadmin blocks
243      */

244     public int getState() {
245         if (ihContext != null) {
246             if (ihContext.isMarkedRemoved()) {
247                 return 4;
248             } else {
249                 if (inDirtyList) {
250                     return 1;
251                 } else {
252                     if (itContext == null) {
253                         return 2;
254                     }
255                 }
256             }
257         }
258         if (itContext != null) {
259             if (itContext.isMarkedRemoved()) {
260                 return 4;
261             } else {
262                 if (runningtx != null) {
263                     return 0;
264                 } else {
265                     return 2;
266                 }
267             }
268         }
269         return 3;
270     }
271
272 }
273
Popular Tags