Main Page | Packages | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages

RAIDb0PessimisticTransactionLevelScheduler.java

00001 /**
00002  * C-JDBC: Clustered JDBC.
00003  * Copyright (C) 2002-2004 French National Institute For Research In Computer
00004  * Science And Control (INRIA).
00005  * Contact: c-jdbc@objectweb.org
00006  * 
00007  * This library is free software; you can redistribute it and/or modify it
00008  * under the terms of the GNU Lesser General Public License as published by the
00009  * Free Software Foundation; either version 2.1 of the License, or any later
00010  * version.
00011  * 
00012  * This library is distributed in the hope that it will be useful, but WITHOUT
00013  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
00015  * for more details.
00016  * 
00017  * You should have received a copy of the GNU Lesser General Public License
00018  * along with this library; if not, write to the Free Software Foundation,
00019  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00020  *
00021  * Initial developer(s): Emmanuel Cecchet. 
00022  * Contributor(s): _________________________.
00023  */
00024 
00025 package org.objectweb.cjdbc.controller.scheduler.raidb0;
00026 
00027 import java.sql.SQLException;
00028 
00029 import org.objectweb.cjdbc.common.sql.AbstractWriteRequest;
00030 import org.objectweb.cjdbc.common.sql.ParsingGranularities;
00031 import org.objectweb.cjdbc.common.sql.SelectRequest;
00032 import org.objectweb.cjdbc.common.util.Constants;
00033 import org.objectweb.cjdbc.common.xml.DatabasesXmlTags;
00034 import org.objectweb.cjdbc.controller.requestmanager.RAIDbLevels;
00035 import org.objectweb.cjdbc.controller.scheduler.AbstractScheduler;
00036 import org.objectweb.cjdbc.controller.scheduler.schema.TransactionExclusiveLock;
00037 
00038 /**
00039  * This scheduler provides transaction level scheduling for RAIDb-0
00040  * controllers. Each write takes a lock on the whole database. All following
00041  * writes are blocked until the transaction of the first write completes.
00042  * 
00043  * @author <a href="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet</a>
00044  * @version 1.0
00045  */
00046 public class RAIDb0PessimisticTransactionLevelScheduler
00047     extends
00048       AbstractScheduler
00049 {
00050 
00051   //
00052   // How the code is organized ?
00053   //
00054   // 1. Member variables
00055   // 2. Constructor
00056   // 3. Request handling
00057   // 4. Transaction management
00058   // 5. Debug/Monitoring
00059   //
00060 
00061   private long                     requestId;
00062   private TransactionExclusiveLock lock = new TransactionExclusiveLock();
00063 
00064   //
00065   // Constructor
00066   //
00067 
00068   /**
00069    * Creates a new Pessimistic Transaction Level Scheduler
00070    */
00071   public RAIDb0PessimisticTransactionLevelScheduler()
00072   {
00073     super(RAIDbLevels.RAIDb0, ParsingGranularities.NO_PARSING);
00074   }
00075 
00076   //
00077   // Request Handling
00078   //
00079 
00080   /**
00081    * Additionally to scheduling the request, this method replaces the SQL Date
00082    * macros such as now() with the current date.
00083    * 
00084    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#scheduleReadRequest(SelectRequest)
00085    */
00086   public final void scheduleReadRequest(SelectRequest request)
00087       throws SQLException
00088   {
00089     synchronized (this)
00090     {
00091       request.setId(requestId++);
00092     }
00093   }
00094 
00095   /**
00096    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#readCompletedNotify(SelectRequest)
00097    */
00098   public final void readCompletedNotify(SelectRequest request)
00099   {
00100   }
00101 
00102   /**
00103    * Additionally to scheduling the request, this method replaces the SQL Date
00104    * macros such as now() with the current date. Note that CREATE statements
00105    * are not synchronized.
00106    * 
00107    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#scheduleWriteRequest(AbstractWriteRequest)
00108    */
00109   public void scheduleNonSuspendedWriteRequest(AbstractWriteRequest request)
00110       throws SQLException
00111   {
00112     if (request.isCreate())
00113     {
00114       synchronized (this)
00115       {
00116         request.setId(requestId++);
00117       }
00118       return;
00119     }
00120 
00121     if (lock.acquire(request))
00122     {
00123       synchronized (this)
00124       {
00125         request.setId(requestId++);
00126       }
00127       if (logger.isDebugEnabled())
00128         logger.debug("Request " + request.getId() + " scheduled for write ("
00129             + getPendingWrites() + " pending writes)");
00130     }
00131     else
00132     {
00133       if (logger.isWarnEnabled())
00134         logger.warn("Request " + request.getId() + " timed out ("
00135             + request.getTimeout() + " s)");
00136       throw new SQLException("Timeout (" + request.getTimeout()
00137           + ") for request: "
00138           + request.getSQLShortForm(Constants.SQL_SHORT_FORM_LENGTH));
00139     }
00140   }
00141 
00142   /**
00143    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#notifyWriteCompleted(AbstractWriteRequest)
00144    */
00145   public final synchronized void notifyWriteCompleted(
00146       AbstractWriteRequest request)
00147   {
00148     // Requests outside transaction delimiters must release the lock
00149     // as soon as they have executed
00150     if (request.isAutoCommit() && (!request.isCreate()))
00151       releaseLock(request.getTransactionId());
00152   }
00153 
00154   //
00155   // Transaction Management
00156   //
00157 
00158   /**
00159    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#commitTransaction(long)
00160    */
00161   protected final void commitTransaction(long transactionId)
00162   {
00163     releaseLock(transactionId);
00164   }
00165 
00166   /**
00167    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#rollbackTransaction(long)
00168    */
00169   protected final void rollbackTransaction(long transactionId)
00170   {
00171     releaseLock(transactionId);
00172   }
00173 
00174   /**
00175    * Release the locks we may own on the schema.
00176    * 
00177    * @param transactionId id of the transaction that releases the lock
00178    */
00179   private void releaseLock(long transactionId)
00180   {
00181     // Are we the lock owner ?
00182     if (lock.isLocked())
00183     {
00184       if (lock.getLocker() == transactionId)
00185         lock.release();
00186 
00187       // Note that the following warnings could be safely ignored if the
00188       // transaction
00189       // commiting/rolllbacking (releasing the lock) has not done any
00190       // conflicting write
00191       else if (logger.isDebugEnabled())
00192         logger.debug("Transaction " + transactionId
00193             + " wants to release the lock held by transaction "
00194             + lock.getLocker());
00195     }
00196     else if (logger.isDebugEnabled())
00197       logger.warn("Transaction " + transactionId
00198           + " tries to release a lock that has not been acquired.");
00199   }
00200 
00201   //
00202   // Debug/Monitoring
00203   //
00204 
00205   /**
00206    * @see org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#getXmlImpl()
00207    */
00208   public String getXmlImpl()
00209   {
00210     StringBuffer info = new StringBuffer();
00211     info.append("<" + DatabasesXmlTags.ELT_RAIDb0Scheduler + " "
00212         + DatabasesXmlTags.ATT_level + "=\""
00213         + DatabasesXmlTags.VAL_pessimisticTransaction + "\"/>");
00214     return info.toString();
00215   }
00216 
00217 }

Generated on Mon Apr 11 22:01:33 2005 for C-JDBC by  doxygen 1.3.9.1