KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > cjdbc > controller > scheduler > raidb1 > RAIDb1PessimisticTransactionLevelScheduler


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.raidb1;
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-1 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 RAIDb1PessimisticTransactionLevelScheduler
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
66   TransactionExclusiveLock lock = new TransactionExclusiveLock();
67
68   //
69
// Constructor
70
//
71

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

75   public RAIDb1PessimisticTransactionLevelScheduler()
76   {
77     super(RAIDbLevels.RAIDb1, ParsingGranularities.NO_PARSING);
78   }
79
80   //
81
// Request Handling
82
//
83

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

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

102   public final void readCompletedNotify(SelectRequest request)
103   {
104   }
105
106   /**
107    * Note that CREATE statements are not synchronized.
108    *
109    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#scheduleNonSuspendedWriteRequest(AbstractWriteRequest)
110    */

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

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

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

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

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

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

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

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

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

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

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

277   public String JavaDoc getXmlImpl()
278   {
279     return "<" + DatabasesXmlTags.ELT_RAIDb1Scheduler + " "
280         + DatabasesXmlTags.ATT_level + "=\""
281         + DatabasesXmlTags.VAL_pessimisticTransaction + "\"/>";
282   }
283 }
284
Popular Tags