KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > cjdbc > controller > scheduler > raidb0 > RAIDb0PessimisticTransactionLevelScheduler


1 /**
2  * C-JDBC: Clustered JDBC.
3  * Copyright (C) 2002-2005 French National Institute For Research In Computer
4  * Science And Control (INRIA).
5  * Contact: c-jdbc@objectweb.org
6  *
7  * This library is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by the
9  * Free Software Foundation; either version 2.1 of the License, or any later
10  * version.
11  *
12  * This library is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20  *
21  * Initial developer(s): Emmanuel Cecchet.
22  * Contributor(s): Jean-Bernard van Zuylen.
23  */

24
25 package org.objectweb.cjdbc.controller.scheduler.raidb0;
26
27 import java.sql.SQLException JavaDoc;
28
29 import org.objectweb.cjdbc.common.exceptions.RollbackException;
30 import org.objectweb.cjdbc.common.sql.AbstractWriteRequest;
31 import org.objectweb.cjdbc.common.sql.ParsingGranularities;
32 import org.objectweb.cjdbc.common.sql.SelectRequest;
33 import org.objectweb.cjdbc.common.sql.StoredProcedure;
34 import org.objectweb.cjdbc.common.util.Constants;
35 import org.objectweb.cjdbc.common.xml.DatabasesXmlTags;
36 import org.objectweb.cjdbc.controller.requestmanager.RAIDbLevels;
37 import org.objectweb.cjdbc.controller.scheduler.AbstractScheduler;
38 import org.objectweb.cjdbc.controller.scheduler.schema.TransactionExclusiveLock;
39
40 /**
41  * This scheduler provides transaction level scheduling for RAIDb-0 controllers.
42  * Each write takes a lock on the whole database. All following writes are
43  * blocked until the transaction of the first write completes.
44  *
45  * @author <a HREF="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet</a>
46  * @author <a HREF="mailto:jbvanzuylen@transwide.com">Jean-Bernard van Zuylen
47  * </a>
48  * @version 1.0
49  */

50 public class RAIDb0PessimisticTransactionLevelScheduler
51     extends AbstractScheduler
52 {
53
54   //
55
// How the code is organized ?
56
//
57
// 1. Member variables
58
// 2. Constructor
59
// 3. Request handling
60
// 4. Transaction management
61
// 5. Debug/Monitoring
62
//
63

64   private long requestId;
65   private TransactionExclusiveLock lock = new TransactionExclusiveLock();
66
67   //
68
// Constructor
69
//
70

71   /**
72    * Creates a new Pessimistic Transaction Level Scheduler
73    */

74   public RAIDb0PessimisticTransactionLevelScheduler()
75   {
76     super(RAIDbLevels.RAIDb0, ParsingGranularities.NO_PARSING);
77   }
78
79   //
80
// Request Handling
81
//
82

83   /**
84    * Additionally to scheduling the request, this method replaces the SQL Date
85    * macros such as now() with the current date.
86    *
87    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#scheduleReadRequest(SelectRequest)
88    */

89   public final void scheduleReadRequest(SelectRequest request)
90       throws SQLException JavaDoc
91   {
92     synchronized (this)
93     {
94       request.setId(requestId++);
95     }
96   }
97
98   /**
99    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#readCompletedNotify(SelectRequest)
100    */

101   public final void readCompletedNotify(SelectRequest request)
102   {
103   }
104
105   /**
106    * Additionally to scheduling the request, this method replaces the SQL Date
107    * macros such as now() with the current date. Note that CREATE statements are
108    * not synchronized.
109    *
110    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#scheduleWriteRequest(AbstractWriteRequest)
111    */

112   public void scheduleNonSuspendedWriteRequest(AbstractWriteRequest request)
113       throws SQLException JavaDoc
114   {
115     if (request.isCreate())
116     {
117       synchronized (this)
118       {
119         request.setId(requestId++);
120       }
121       return;
122     }
123
124     if (lock.acquire(request))
125     {
126       synchronized (this)
127       {
128         request.setId(requestId++);
129       }
130       if (logger.isDebugEnabled())
131         logger.debug("Request " + request.getId() + " scheduled for write ("
132             + getPendingWrites() + " pending writes)");
133     }
134     else
135     {
136       if (logger.isWarnEnabled())
137         logger.warn("Request " + request.getId() + " timed out ("
138             + request.getTimeout() + " s)");
139       throw new SQLException JavaDoc("Timeout (" + request.getTimeout()
140           + ") for request: "
141           + request.getSQLShortForm(Constants.SQL_SHORT_FORM_LENGTH));
142     }
143   }
144
145   /**
146    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#notifyWriteCompleted(AbstractWriteRequest)
147    */

148   public final synchronized void notifyWriteCompleted(
149       AbstractWriteRequest request)
150   {
151     // Requests outside transaction delimiters must release the lock
152
// as soon as they have executed
153
if (request.isAutoCommit() && (!request.isCreate()))
154       releaseLock(request.getTransactionId());
155   }
156
157   /**
158    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#scheduleNonSuspendedStoredProcedure(org.objectweb.cjdbc.common.sql.StoredProcedure)
159    */

160   public final synchronized void scheduleNonSuspendedStoredProcedure(
161       StoredProcedure proc) throws SQLException JavaDoc, RollbackException
162   {
163     if (lock.acquire(proc))
164     {
165       synchronized (this)
166       {
167         proc.setId(requestId++);
168       }
169       if (logger.isDebugEnabled())
170         logger.debug("Stored procedure " + proc.getId()
171             + " scheduled for write (" + getPendingWrites()
172             + " pending writes)");
173     }
174     else
175     {
176       if (logger.isWarnEnabled())
177         logger.warn("Stored procedure " + proc.getId() + " timed out ("
178             + proc.getTimeout() + " s)");
179       throw new SQLException JavaDoc("Timeout (" + proc.getTimeout()
180           + ") for request: "
181           + proc.getSQLShortForm(Constants.SQL_SHORT_FORM_LENGTH));
182     }
183   }
184
185   /**
186    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#notifyStoredProcedureCompleted(org.objectweb.cjdbc.common.sql.StoredProcedure)
187    */

188   public final void notifyStoredProcedureCompleted(StoredProcedure proc)
189   {
190     // Requests outside transaction delimiters must release the lock
191
// as soon as they have executed
192
if (proc.isAutoCommit() && (!proc.isCreate()))
193       releaseLock(proc.getTransactionId());
194   }
195
196   //
197
// Transaction Management
198
//
199

200   /**
201    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#commitTransaction(long)
202    */

203   protected final void commitTransaction(long transactionId)
204   {
205     releaseLock(transactionId);
206   }
207
208   /**
209    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#rollbackTransaction(long)
210    */

211   protected final void rollbackTransaction(long transactionId)
212   {
213     releaseLock(transactionId);
214   }
215
216   /**
217    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#rollbackTransaction(long,
218    * String)
219    */

220   protected final void rollbackTransaction(long transactionId,
221       String JavaDoc savepointName)
222   {
223   }
224
225   /**
226    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#setSavepointTransaction(long,
227    * String)
228    */

229   protected final void setSavepointTransaction(long transactionId, String JavaDoc name)
230   {
231   }
232
233   /**
234    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#releaseSavepointTransaction(long,
235    * String)
236    */

237   protected final void releaseSavepointTransaction(long transactionId,
238       String JavaDoc name)
239   {
240   }
241
242   /**
243    * Release the locks we may own on the schema.
244    *
245    * @param transactionId id of the transaction that releases the lock
246    */

247   private void releaseLock(long transactionId)
248   {
249     // Are we the lock owner ?
250
if (lock.isLocked())
251     {
252       if (lock.getLocker() == transactionId)
253         lock.release();
254
255       // Note that the following warnings could be safely ignored if the
256
// transaction
257
// commiting/rolllbacking (releasing the lock) has not done any
258
// conflicting write
259
else if (logger.isDebugEnabled())
260         logger.debug("Transaction " + transactionId
261             + " wants to release the lock held by transaction "
262             + lock.getLocker());
263     }
264     else if (logger.isDebugEnabled())
265       logger.warn("Transaction " + transactionId
266           + " tries to release a lock that has not been acquired.");
267   }
268
269   //
270
// Debug/Monitoring
271
//
272

273   /**
274    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#getXmlImpl()
275    */

276   public String JavaDoc getXmlImpl()
277   {
278     StringBuffer JavaDoc info = new StringBuffer JavaDoc();
279     info.append("<" + DatabasesXmlTags.ELT_RAIDb0Scheduler + " "
280         + DatabasesXmlTags.ATT_level + "=\""
281         + DatabasesXmlTags.VAL_pessimisticTransaction + "\"/>");
282     return info.toString();
283   }
284 }
285
Popular Tags