KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > cjdbc > controller > scheduler > raidb2 > RAIDb2PessimisticTransactionLevelScheduler


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.raidb2;
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-2 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 RAIDb2PessimisticTransactionLevelScheduler
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 RAIDb2PessimisticTransactionLevelScheduler()
75   {
76     super(RAIDbLevels.RAIDb2, 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    * Note that CREATE statements are not synchronized.
107    *
108    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#scheduleWriteRequest(AbstractWriteRequest)
109    */

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

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

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

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

197   /**
198    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#commitTransaction(long)
199    */

200   protected final void commitTransaction(long transactionId)
201   {
202     if (lock.isLocked())
203       releaseLock(transactionId);
204     // else this was an empty or read-only transaction
205
}
206
207   /**
208    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#rollbackTransaction(long)
209    */

210   protected final void rollbackTransaction(long transactionId)
211   {
212     if (lock.isLocked())
213       releaseLock(transactionId);
214     // else this was an empty or read-only transaction
215
}
216
217   /**
218    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#rollbackTransaction(long,
219    * String)
220    */

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

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

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

248   private void releaseLock(long transactionId)
249   {
250     // Are we the lock owner ?
251
if (lock.isLocked())
252     {
253       if (lock.getLocker() == transactionId)
254         lock.release();
255
256       // Note that the following warnings could be safely ignored if the
257
// transaction commiting/rollbacking (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     return "<" + DatabasesXmlTags.ELT_RAIDb2Scheduler + " "
279         + DatabasesXmlTags.ATT_level + "=\""
280         + DatabasesXmlTags.VAL_pessimisticTransaction + "\"/>";
281   }
282 }
283
Popular Tags