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.raidb1;
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-1 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 RAIDb1PessimisticTransactionLevelScheduler 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: TransactionExclusiveLock lock = new TransactionExclusiveLock();
062:
063: //
064: // Constructor
065: //
066:
067: /**
068: * Creates a new Pessimistic Transaction Level Scheduler
069: */
070: public RAIDb1PessimisticTransactionLevelScheduler() {
071: super (RAIDbLevels.RAIDb1, 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: * Note that CREATE statements are not synchronized.
096: *
097: * @see org.continuent.sequoia.controller.scheduler.AbstractScheduler#scheduleNonSuspendedWriteRequest(AbstractWriteRequest)
098: */
099: public void scheduleNonSuspendedWriteRequest(
100: AbstractWriteRequest request) throws SQLException {
101: if (request.isCreate()) {
102: return;
103: }
104:
105: if (lock.acquire(request)) {
106: if (logger.isDebugEnabled())
107: logger.debug("Request " + request.getId()
108: + " scheduled for write (" + getPendingWrites()
109: + " pending writes)");
110: } else {
111: if (logger.isWarnEnabled())
112: logger
113: .warn("Request " + request.getId()
114: + " timed out (" + request.getTimeout()
115: + " s)");
116: throw new SQLException(
117: "Timeout ("
118: + request.getTimeout()
119: + ") for request: "
120: + request
121: .getSqlShortForm(ControllerConstants.SQL_SHORT_FORM_LENGTH));
122: }
123: }
124:
125: /**
126: * @see org.continuent.sequoia.controller.scheduler.AbstractScheduler#notifyWriteCompleted(AbstractWriteRequest)
127: */
128: public final void notifyWriteCompleted(AbstractWriteRequest request) {
129: // Requests outside transaction delimiters must release the lock
130: // as soon as they have executed
131: if (request.isAutoCommit() && (!request.isCreate()))
132: releaseLock(request.getTransactionId());
133: }
134:
135: /**
136: * @see org.continuent.sequoia.controller.scheduler.AbstractScheduler#scheduleNonSuspendedStoredProcedure(org.continuent.sequoia.controller.requests.StoredProcedure)
137: */
138: public final void scheduleNonSuspendedStoredProcedure(
139: StoredProcedure proc) throws SQLException,
140: RollbackException {
141: if (lock.acquire(proc)) {
142: if (logger.isDebugEnabled())
143: logger.debug("Stored procedure " + proc.getId()
144: + " scheduled for write (" + getPendingWrites()
145: + " pending writes)");
146: } else {
147: if (logger.isWarnEnabled())
148: logger.warn("Stored procedure " + proc.getId()
149: + " timed out (" + proc.getTimeout() + " s)");
150: throw new SQLException(
151: "Timeout ("
152: + proc.getTimeout()
153: + ") for request: "
154: + proc
155: .getSqlShortForm(ControllerConstants.SQL_SHORT_FORM_LENGTH));
156: }
157: }
158:
159: /**
160: * @see org.continuent.sequoia.controller.scheduler.AbstractScheduler#notifyStoredProcedureCompleted(org.continuent.sequoia.controller.requests.StoredProcedure)
161: */
162: public final void notifyStoredProcedureCompleted(
163: StoredProcedure proc) {
164: // Requests outside transaction delimiters must release the lock
165: // as soon as they have executed
166: if (proc.isAutoCommit() && (!proc.isCreate()))
167: releaseLock(proc.getTransactionId());
168: }
169:
170: //
171: // Transaction Management
172: //
173:
174: /**
175: * @see org.continuent.sequoia.controller.scheduler.AbstractScheduler#commitTransaction(long)
176: */
177: protected final void commitTransaction(long transactionId) {
178: if (lock.isLocked())
179: releaseLock(transactionId);
180: // else this was an empty or read-only transaction
181: }
182:
183: /**
184: * @see org.continuent.sequoia.controller.scheduler.AbstractScheduler#rollbackTransaction(long)
185: */
186: protected final void rollbackTransaction(long transactionId) {
187: if (lock.isLocked())
188: releaseLock(transactionId);
189: // else this was an empty or read-only transaction
190: }
191:
192: /**
193: * @see org.continuent.sequoia.controller.scheduler.AbstractScheduler#rollbackTransaction(long,
194: * String)
195: */
196: protected final void rollbackTransaction(long transactionId,
197: String savepointName) {
198: }
199:
200: /**
201: * @see org.continuent.sequoia.controller.scheduler.AbstractScheduler#setSavepointTransaction(long,
202: * String)
203: */
204: protected final void setSavepointTransaction(long transactionId,
205: String name) {
206: }
207:
208: /**
209: * @see org.continuent.sequoia.controller.scheduler.AbstractScheduler#releaseSavepointTransaction(long,
210: * String)
211: */
212: protected final void releaseSavepointTransaction(
213: long transactionId, String name) {
214: }
215:
216: /**
217: * Release the locks we may own on the schema.
218: *
219: * @param transactionId id of the transaction that releases the lock
220: */
221: private void releaseLock(long transactionId) {
222: // Are we the lock owner ?
223: if (lock.isLocked()) {
224: if (lock.getLocker() == transactionId)
225: lock.release();
226:
227: // Note that the following warnings could be safely ignored if the
228: // transaction commiting/rollbacking (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: * @see org.continuent.sequoia.controller.scheduler.AbstractScheduler#getXmlImpl()
248: */
249: public String getXmlImpl() {
250: return "<" + DatabasesXmlTags.ELT_RAIDb1Scheduler + " "
251: + DatabasesXmlTags.ATT_level + "=\""
252: + DatabasesXmlTags.VAL_pessimisticTransaction + "\"/>";
253: }
254: }
|