KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > cjdbc > controller > scheduler > singledb > SingleDBPessimisticTransactionLevelScheduler


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.singledb;
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 a SingleDB. Each
42  * write takes a lock on the whole database. All following writes are blocked
43  * until the transaction of the first write completes.
44  *
45  * @author <a HREF="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
46  * @version 1.0
47  */

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

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

69   /**
70    * Creates a new Pessimistic Transaction Level Scheduler
71    */

72   public SingleDBPessimisticTransactionLevelScheduler()
73   {
74     super(RAIDbLevels.SingleDB, ParsingGranularities.NO_PARSING);
75   }
76
77   //
78
// Request Handling
79
//
80

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

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

96   public final void readCompletedNotify(SelectRequest request)
97   {
98   }
99
100   /**
101    * Additionally to scheduling the request, this method replaces the SQL Date
102    * macros such as now() with the current date.
103    *
104    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#scheduleWriteRequest(AbstractWriteRequest)
105    */

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

132   public final synchronized void notifyWriteCompleted(
133       AbstractWriteRequest request)
134   {
135     // Requests outside transaction delimiters must release the lock
136
// as soon as they have executed
137
if (request.isAutoCommit())
138       releaseLock(request.getTransactionId());
139   }
140
141   /**
142    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#scheduleNonSuspendedStoredProcedure(org.objectweb.cjdbc.common.sql.StoredProcedure)
143    */

144   public final synchronized void scheduleNonSuspendedStoredProcedure(
145       StoredProcedure proc) throws SQLException JavaDoc, RollbackException
146   {
147     if (lock.acquire(proc))
148     {
149       synchronized (this)
150       {
151         proc.setId(requestId++);
152       }
153       if (logger.isDebugEnabled())
154         logger.debug("Stored procedure " + proc.getId()
155             + " scheduled for write (" + getPendingWrites()
156             + " pending writes)");
157     }
158     else
159     {
160       if (logger.isWarnEnabled())
161         logger.warn("Stored procedure " + proc.getId() + " timed out ("
162             + proc.getTimeout() + " s)");
163       throw new SQLException JavaDoc("Timeout (" + proc.getTimeout()
164           + ") for request: "
165           + proc.getSQLShortForm(Constants.SQL_SHORT_FORM_LENGTH));
166     }
167   }
168
169   /**
170    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#notifyStoredProcedureCompleted(org.objectweb.cjdbc.common.sql.StoredProcedure)
171    */

172   public final void notifyStoredProcedureCompleted(StoredProcedure proc)
173   {
174     // Requests outside transaction delimiters must release the lock
175
// as soon as they have executed
176
if (proc.isAutoCommit() && (!proc.isCreate()))
177       releaseLock(proc.getTransactionId());
178   }
179
180   //
181
// Transaction Management
182
//
183

184   /**
185    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#commitTransaction(long)
186    */

187   protected final void commitTransaction(long transactionId)
188   {
189     releaseLock(transactionId);
190   }
191
192   /**
193    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#rollbackTransaction(long)
194    */

195   protected final void rollbackTransaction(long transactionId)
196   {
197     releaseLock(transactionId);
198   }
199
200   /**
201    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#rollbackTransaction(long,
202    * String)
203    */

204   protected final void rollbackTransaction(long transactionId,
205       String JavaDoc savepointName)
206   {
207   }
208
209   /**
210    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#setSavepointTransaction(long,
211    * String)
212    */

213   protected final void setSavepointTransaction(long transactionId, String JavaDoc name)
214   {
215   }
216
217   /**
218    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#releaseSavepointTransaction(long,
219    * String)
220    */

221   protected final void releaseSavepointTransaction(long transactionId,
222       String JavaDoc name)
223   {
224   }
225
226   /**
227    * Release the locks we may own on the schema.
228    *
229    * @param transactionId id of the transaction that releases the lock
230    */

231   private void releaseLock(long transactionId)
232   {
233     // Are we the lock owner ?
234
if (lock.isLocked())
235     {
236       if (lock.getLocker() == transactionId)
237         lock.release();
238
239       // Note that the following warnings could be safely ignored if the
240
// transaction
241
// commiting/rolllbacking (releasing the lock) has not done any
242
// conflicting write
243
else if (logger.isDebugEnabled())
244         logger.debug("Transaction " + transactionId
245             + " wants to release the lock held by transaction "
246             + lock.getLocker());
247     }
248     else if (logger.isDebugEnabled())
249       logger.warn("Transaction " + transactionId
250           + " tries to release a lock that has not been acquired.");
251   }
252
253   //
254
// Debug/Monitoring
255
//
256

257   /**
258    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#getXmlImpl()
259    */

260   public String JavaDoc getXmlImpl()
261   {
262     return "<" + DatabasesXmlTags.ELT_SingleDBScheduler + " "
263         + DatabasesXmlTags.ATT_level + "=\""
264         + DatabasesXmlTags.VAL_pessimisticTransaction + "\"/>";
265   }
266 }
267
Popular Tags