KickJava   Java API By Example, From Geeks To Geeks.

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


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: JEntitySwitchCRU.java,v 1.19 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.transaction.SystemException JavaDoc;
30 import javax.transaction.Transaction JavaDoc;
31
32 import org.objectweb.jonas_ejb.deployment.api.EntityDesc;
33
34 import org.objectweb.util.monolog.api.BasicLevel;
35
36 /**
37  * Container Read Uncommitted lock-policy.
38  * Only 1 thread can write. All other threads can read, without
39  * waiting for a committed state. There is no wait.
40  * @author Philippe Durieux
41  */

42 public class JEntitySwitchCRU extends JEntitySwitch {
43
44     /**
45      * unique EntityContext
46      */

47     protected JEntityContext itContext = null;
48
49     /**
50      * empty constructor. Object is initialized via init() because it is
51      * implemented differently according to jorm mappers.
52      */

53     public JEntitySwitchCRU() {
54         lockpolicy = EntityDesc.LOCK_CONTAINER_READ_UNCOMMITTED;
55         txUpdates = true;
56     }
57
58     protected void initpolicy(JEntityFactory bf) {
59         lazyregister = true;
60     }
61
62     protected JEntityContext getContext4Tx(Transaction JavaDoc tx) {
63         return itContext;
64     }
65
66     protected void setContext4Tx(Transaction JavaDoc tx, JEntityContext ctx) {
67         itContext = ctx;
68     }
69
70     protected void removeContext4Tx(Transaction JavaDoc tx) {
71         itContext = null;
72     }
73
74     public void waitmyturn(Transaction JavaDoc tx) {
75         // No synchro for this policy.
76
}
77
78     /**
79      * Map a context and its instance.
80      * @param tx - the Transaction object
81      * @param bctx - the JEntityContext to bind if not null
82      * @param forced - force to take this context. (case of create)
83      * @param holdit - increment count to hold it, a release will be called
84      * later.
85      * @return JEntityContext actually mapped
86      */

87     public synchronized JEntityContext mapICtx(Transaction JavaDoc tx, JEntityContext bctx, boolean forced, boolean holdit, boolean notused) {
88
89         waitmyturn(tx);
90
91         // Choose the context to use.
92
boolean newtrans = false;
93         JEntityContext jec = itContext;
94         if (forced) {
95             // If the new context is enforced, we must first release the older
96
if (jec != null) {
97                 if (TraceEjb.isDebugContext()) {
98                     TraceEjb.context.log(BasicLevel.DEBUG, ident + "new context is enforced!");
99                 }
100                 discardContext(tx, false, true);
101             }
102             jec = bctx;
103             itContext = jec;
104             jec.initEntityContext(this);
105             newtrans = true;
106         } else {
107             if (jec != null) {
108                 // Reuse the Context for this transaction.
109
// If a context was supplied, release it first.
110
if (bctx != null) {
111                     if (TraceEjb.isDebugContext()) {
112                             TraceEjb.context.log(BasicLevel.DEBUG, ident + "a context was supplied!");
113                     }
114                     bf.releaseJContext(bctx);
115                 }
116                 newtrans = true; // TODO: not always a new tx (if more than 1
117
// modifying call on this)
118
jec.reuseEntityContext(newtrans);
119             } else {
120                 if (bctx != null) {
121                     jec = bctx;
122                 } else {
123                     // no Context available : get one from the pool.
124
jec = (JEntityContext) bf.getJContext(this);
125                 }
126                 jec.initEntityContext(this);
127                 jec.activate(true);
128                 itContext = jec; // after activate
129
newtrans = true;
130             }
131         }
132
133         if (tx == null) {
134             if (holdit) {
135                 countIH++;
136                 if (TraceEjb.isDebugSynchro()) {
137                         TraceEjb.synchro.log(BasicLevel.DEBUG, ident + "mapICtx IH count=" + countIH);
138                 }
139                 if (shared && countIH == 1) {
140                     // reload state that could have been modified by
141
// transactions.
142
jec.activate(false);
143                 }
144             }
145         } else {
146             if (holdit) {
147                 countIT++;
148             }
149         }
150
151         return jec;
152     }
153
154     /**
155      * never called ?
156      */

157     public boolean passivateIH(boolean passivation) {
158         JEntityContext jec = getContext4Tx(null);
159         // If already passivated, look if we can destroy the objects
160
if (jec == null) {
161             if (inactivityTimeout > 0 &&
162                 System.currentTimeMillis() - timestamp > inactivityTimeout) {
163                 if (TraceEjb.isDebugContext()) {
164                     TraceEjb.context.log(BasicLevel.DEBUG, "discard object on timeout");
165                 }
166                 discardContext(null, true, false);
167             }
168             return true;
169         }
170         // passivate this instance if required.
171
if (passivation) {
172             if (TraceEjb.isDebugContext()) {
173                 TraceEjb.context.log(BasicLevel.DEBUG, "TODO: passivate: " + jec);
174             }
175         }
176         return true;
177     }
178
179     public void endIH() {
180         return; // NEVER
181
}
182
183     /**
184      * This transaction has just modified this instance. (CMP2 only)
185      * @param tx transaction
186      */

187     public synchronized void notifyWriting(Transaction JavaDoc tx, JEntityContext bctx) {
188         if (TraceEjb.isDebugSynchro()) {
189             TraceEjb.synchro.log(BasicLevel.DEBUG, ident);
190         }
191         if (writingtx != null) {
192             if (!tx.equals(writingtx)) {
193                 TraceEjb.logger.log(BasicLevel.WARN, "");
194                 try {
195                     tx.setRollbackOnly();
196                 } catch (SystemException JavaDoc e) {
197                     TraceEjb.logger.log(BasicLevel.ERROR, "cannot set current transaction RollbackOnly");
198                 }
199                 // Since we share the same instance, we must rollback also
200
// the current transaction (else data would be corrupted).
201
try {
202                     writingtx.setRollbackOnly();
203                 } catch (SystemException JavaDoc e) {
204                     TraceEjb.logger.log(BasicLevel.ERROR, "cannot set other transaction RollbackOnly");
205                 }
206                 // We should also avoid modifying instance, in case writingtx is
207
// already committing (setRollbackOnly will fail)
208
throw new EJBException JavaDoc("Conflict writing entity bean");
209             }
210         } else {
211             // Instance must be written later.
212
registerCtx(tx, bctx);
213             writingtx = tx;
214         }
215     }
216
217     /**
218      * @return State of this instance. State values are 0=in-tx, 1=out-tx, 2=idle,
219      * 3=passive, 4=removed. we don't synchronize this method to avoid
220      * jadmin blocks
221      */

222     public int getState() {
223         if (itContext != null) {
224             if (itContext.isMarkedRemoved()) {
225                 return 4;
226             } else {
227                 if (writingtx != null) {
228                     return 0;
229                 } else {
230                     return 1;
231                 }
232             }
233         }
234         return 3;
235     }
236
237 }
238
Popular Tags