001: /**
002: * Sequoia: Database clustering technology.
003: * Copyright (C) 2002-2004 French National Institute For Research In Computer
004: * Science And Control (INRIA).
005: * Copyright (C) 2005 AmicoSoft, Inc. dba Emic Networks
006: * Contact: sequoia@continuent.org
007: *
008: * Licensed under the Apache License, Version 2.0 (the "License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: * Initial developer(s): Emmanuel Cecchet.
021: * Contributor(s): Jean-Bernard van Zuylen.
022: */package org.continuent.sequoia.controller.scheduler.raidb0;
023:
024: import java.sql.SQLException;
025:
026: import org.continuent.sequoia.common.exceptions.RollbackException;
027: import org.continuent.sequoia.common.xml.DatabasesXmlTags;
028: import org.continuent.sequoia.controller.core.ControllerConstants;
029: import org.continuent.sequoia.controller.requestmanager.RAIDbLevels;
030: import org.continuent.sequoia.controller.requests.AbstractWriteRequest;
031: import org.continuent.sequoia.controller.requests.ParsingGranularities;
032: import org.continuent.sequoia.controller.requests.SelectRequest;
033: import org.continuent.sequoia.controller.requests.StoredProcedure;
034: import org.continuent.sequoia.controller.scheduler.AbstractScheduler;
035: import org.continuent.sequoia.controller.scheduler.schema.TransactionExclusiveLock;
036:
037: /**
038: * This scheduler provides transaction level scheduling for RAIDb-0 controllers.
039: * Each write takes a lock on the whole database. All following writes are
040: * blocked until the transaction of the first write completes.
041: *
042: * @author <a href="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet</a>
043: * @author <a href="mailto:jbvanzuylen@transwide.com">Jean-Bernard van Zuylen
044: * </a>
045: * @version 1.0
046: * @deprecated since Sequoia 2.2
047: */
048: public class RAIDb0PessimisticTransactionLevelScheduler extends
049: AbstractScheduler {
050:
051: //
052: // How the code is organized ?
053: //
054: // 1. Member variables
055: // 2. Constructor
056: // 3. Request handling
057: // 4. Transaction management
058: // 5. Debug/Monitoring
059: //
060:
061: private TransactionExclusiveLock lock = new TransactionExclusiveLock();
062:
063: //
064: // Constructor
065: //
066:
067: /**
068: * Creates a new Pessimistic Transaction Level Scheduler
069: */
070: public RAIDb0PessimisticTransactionLevelScheduler() {
071: super (RAIDbLevels.RAIDb0, ParsingGranularities.NO_PARSING);
072: }
073:
074: //
075: // Request Handling
076: //
077:
078: /**
079: * Additionally to scheduling the request, this method replaces the SQL Date
080: * macros such as now() with the current date.
081: *
082: * @see org.continuent.sequoia.controller.scheduler.AbstractScheduler#scheduleNonSuspendedReadRequest(SelectRequest)
083: */
084: public final void scheduleNonSuspendedReadRequest(
085: SelectRequest request) throws SQLException {
086: }
087:
088: /**
089: * @see org.continuent.sequoia.controller.scheduler.AbstractScheduler#readCompletedNotify(SelectRequest)
090: */
091: public final void readCompletedNotify(SelectRequest request) {
092: }
093:
094: /**
095: * Additionally to scheduling the request, this method replaces the SQL Date
096: * macros such as now() with the current date. Note that CREATE statements are
097: * not synchronized.
098: *
099: * @see org.continuent.sequoia.controller.scheduler.AbstractScheduler#scheduleWriteRequest(AbstractWriteRequest)
100: */
101: public void scheduleNonSuspendedWriteRequest(
102: AbstractWriteRequest request) throws SQLException {
103: if (request.isCreate()) {
104: return;
105: }
106:
107: if (lock.acquire(request)) {
108: if (logger.isDebugEnabled())
109: logger.debug("Request " + request.getId()
110: + " scheduled for write (" + getPendingWrites()
111: + " pending writes)");
112: } else {
113: if (logger.isWarnEnabled())
114: logger
115: .warn("Request " + request.getId()
116: + " timed out (" + request.getTimeout()
117: + " s)");
118: throw new SQLException(
119: "Timeout ("
120: + request.getTimeout()
121: + ") for request: "
122: + request
123: .getSqlShortForm(ControllerConstants.SQL_SHORT_FORM_LENGTH));
124: }
125: }
126:
127: /**
128: * @see org.continuent.sequoia.controller.scheduler.AbstractScheduler#notifyWriteCompleted(AbstractWriteRequest)
129: */
130: public final synchronized void notifyWriteCompleted(
131: AbstractWriteRequest request) {
132: // Requests outside transaction delimiters must release the lock
133: // as soon as they have executed
134: if (request.isAutoCommit() && (!request.isCreate()))
135: releaseLock(request.getTransactionId());
136: }
137:
138: /**
139: * @see org.continuent.sequoia.controller.scheduler.AbstractScheduler#scheduleNonSuspendedStoredProcedure(org.continuent.sequoia.controller.requests.StoredProcedure)
140: */
141: public final void scheduleNonSuspendedStoredProcedure(
142: StoredProcedure proc) throws SQLException,
143: RollbackException {
144: if (lock.acquire(proc)) {
145: if (logger.isDebugEnabled())
146: logger.debug("Stored procedure " + proc.getId()
147: + " scheduled for write (" + getPendingWrites()
148: + " pending writes)");
149: } else {
150: if (logger.isWarnEnabled())
151: logger.warn("Stored procedure " + proc.getId()
152: + " timed out (" + proc.getTimeout() + " s)");
153: throw new SQLException(
154: "Timeout ("
155: + proc.getTimeout()
156: + ") for request: "
157: + proc
158: .getSqlShortForm(ControllerConstants.SQL_SHORT_FORM_LENGTH));
159: }
160: }
161:
162: /**
163: * @see org.continuent.sequoia.controller.scheduler.AbstractScheduler#notifyStoredProcedureCompleted(org.continuent.sequoia.controller.requests.StoredProcedure)
164: */
165: public final void notifyStoredProcedureCompleted(
166: StoredProcedure proc) {
167: // Requests outside transaction delimiters must release the lock
168: // as soon as they have executed
169: if (proc.isAutoCommit() && (!proc.isCreate()))
170: releaseLock(proc.getTransactionId());
171: }
172:
173: //
174: // Transaction Management
175: //
176:
177: /**
178: * @see org.continuent.sequoia.controller.scheduler.AbstractScheduler#commitTransaction(long)
179: */
180: protected final void commitTransaction(long transactionId) {
181: releaseLock(transactionId);
182: }
183:
184: /**
185: * @see org.continuent.sequoia.controller.scheduler.AbstractScheduler#rollbackTransaction(long)
186: */
187: protected final void rollbackTransaction(long transactionId) {
188: releaseLock(transactionId);
189: }
190:
191: /**
192: * @see org.continuent.sequoia.controller.scheduler.AbstractScheduler#rollbackTransaction(long,
193: * String)
194: */
195: protected final void rollbackTransaction(long transactionId,
196: String savepointName) {
197: }
198:
199: /**
200: * @see org.continuent.sequoia.controller.scheduler.AbstractScheduler#setSavepointTransaction(long,
201: * String)
202: */
203: protected final void setSavepointTransaction(long transactionId,
204: String name) {
205: }
206:
207: /**
208: * @see org.continuent.sequoia.controller.scheduler.AbstractScheduler#releaseSavepointTransaction(long,
209: * String)
210: */
211: protected final void releaseSavepointTransaction(
212: long transactionId, String name) {
213: }
214:
215: /**
216: * Release the locks we may own on the schema.
217: *
218: * @param transactionId id of the transaction that releases the lock
219: */
220: private void releaseLock(long transactionId) {
221: // Are we the lock owner ?
222: if (lock.isLocked()) {
223: if (lock.getLocker() == transactionId)
224: lock.release();
225:
226: // Note that the following warnings could be safely ignored if the
227: // transaction
228: // commiting/rolllbacking (releasing the lock) has not done any
229: // conflicting write
230: else if (logger.isDebugEnabled())
231: logger
232: .debug("Transaction "
233: + transactionId
234: + " wants to release the lock held by transaction "
235: + lock.getLocker());
236: } else if (logger.isDebugEnabled())
237: logger
238: .warn("Transaction "
239: + transactionId
240: + " tries to release a lock that has not been acquired.");
241: }
242:
243: //
244: // Debug/Monitoring
245: //
246:
247: /**
248: * @see org.continuent.sequoia.controller.scheduler.AbstractScheduler#getXmlImpl()
249: */
250: public String getXmlImpl() {
251: StringBuffer info = new StringBuffer();
252: info.append("<" + DatabasesXmlTags.ELT_RAIDb0Scheduler + " "
253: + DatabasesXmlTags.ATT_level + "=\""
254: + DatabasesXmlTags.VAL_pessimisticTransaction + "\"/>");
255: return info.toString();
256: }
257: }
|