001: /*
002:
003: Derby - Class org.apache.derby.impl.store.raw.data.PhysicalUndoOperation
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. 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: */
021:
022: package org.apache.derby.impl.store.raw.data;
023:
024: import org.apache.derby.impl.store.raw.data.BasePage;
025:
026: import org.apache.derby.iapi.services.io.FormatIdUtil;
027: import org.apache.derby.iapi.services.io.StoredFormatIds;
028: import org.apache.derby.iapi.services.sanity.SanityManager;
029:
030: import org.apache.derby.iapi.store.raw.Compensation;
031: import org.apache.derby.iapi.store.raw.Loggable;
032: import org.apache.derby.iapi.store.raw.Page;
033: import org.apache.derby.iapi.store.raw.Transaction;
034: import org.apache.derby.iapi.store.raw.Undoable;
035:
036: import org.apache.derby.iapi.store.raw.log.LogInstant;
037:
038: import org.apache.derby.iapi.error.StandardException;
039: import org.apache.derby.iapi.util.ByteArray;
040:
041: import java.io.OutputStream;
042: import java.io.ObjectInput;
043: import java.io.IOException;
044: import org.apache.derby.iapi.services.io.LimitObjectInput;
045:
046: /**
047: PhysicalUndoOperation is a compensation operation that rolls back the change of
048: an Undo-able operation. A PhysicalUndoOperation itself is not undo-able, i.e,
049: it is loggable but not undoable.
050:
051: <PRE>
052: @format_id LOGOP_PAGE_PHYSICAL_UNDO
053: the formatId is written by FormatIdOutputStream when this object is
054: written out by writeObject
055: @purpose update a physiacl log operation
056: @upgrade
057: @disk_layout
058: PageBasicOperation the super class
059: OptionalData none (compensation operation never have optional data)
060: @end_format
061: </PRE>
062:
063: */
064: public class PhysicalUndoOperation extends PageBasicOperation implements
065: Compensation {
066:
067: /** The operation to be rolled back */
068: transient private PhysicalPageOperation undoOp;
069:
070: protected PhysicalUndoOperation(BasePage page) {
071: super (page);
072: }
073:
074: /** Set up a compensation operation during run time rollback */
075: public PhysicalUndoOperation(BasePage page, PhysicalPageOperation op) {
076: super (page);
077: undoOp = op;
078: }
079:
080: /**
081: Return my format identifier.
082: */
083:
084: // no-arg constructor, required by Formatable
085: public PhysicalUndoOperation() {
086: super ();
087: }
088:
089: public int getTypeFormatId() {
090: return StoredFormatIds.LOGOP_PAGE_PHYSICAL_UNDO;
091: }
092:
093: // no fields, therefore no writeExternal or readExternal
094:
095: /**
096: Compensation methods
097: */
098:
099: /** Set up a PageUndoOperation during recovery redo. */
100: public void setUndoOp(Undoable op) {
101: if (SanityManager.DEBUG) {
102: SanityManager.ASSERT(op instanceof PhysicalPageOperation);
103: }
104: undoOp = (PhysicalPageOperation) op;
105: }
106:
107: /**
108: Loggable methods
109: */
110:
111: /** Apply the undo operation, in this implementation of the
112: RawStore, it can only call the undoMe method of undoOp
113:
114: @param xact the Transaction that is doing the rollback
115: @param instant the log instant of this undo operation
116: @param in optional data
117:
118: @exception IOException Can be thrown by any of the methods of InputStream.
119: @exception StandardException Standard Cloudscape policy.
120:
121: */
122: public final void doMe(Transaction xact, LogInstant instant,
123: LimitObjectInput in) throws StandardException, IOException {
124:
125: long oldversion = 0; // sanity check
126: LogInstant oldLogInstant = null; // sanity check
127: if (SanityManager.DEBUG) {
128: oldLogInstant = this .page.getLastLogInstant();
129: oldversion = this .page.getPageVersion();
130:
131: SanityManager.ASSERT(oldversion == this .getPageVersion());
132: SanityManager.ASSERT(oldLogInstant == null
133: || instant == null
134: || oldLogInstant.lessThan(instant));
135: }
136:
137: // if this is called during runtime rollback, PageOp.generateUndo found
138: // the page and have it latched there.
139: // if this is called during recovery redo, this.needsRedo found the page and
140: // have it latched here
141: //
142: // in either case, this.page is the correct page and is latched.
143: //
144: undoOp.undoMe(xact, this .page, instant, in);
145:
146: if (SanityManager.DEBUG) {
147:
148: if (oldversion >= this .page.getPageVersion()) {
149: SanityManager.THROWASSERT("oldversion = " + oldversion
150: + ";page version = "
151: + this .page.getPageVersion() + "page = " + page
152: + "; my class name is " + getClass().getName()
153: + " undoOp is " + undoOp.getClass().getName());
154: }
155: SanityManager.ASSERT(oldversion < this .page
156: .getPageVersion());
157:
158: if (instant != null
159: && !instant.equals(this .page.getLastLogInstant()))
160: SanityManager.THROWASSERT("my class name is "
161: + getClass().getName() + " undoOp is "
162: + undoOp.getClass().getName());
163: }
164:
165: releaseResource(xact);
166: }
167:
168: /* make sure resource found in undoOp is released */
169: public void releaseResource(Transaction xact) {
170: if (undoOp != null)
171: undoOp.releaseResource(xact);
172: super .releaseResource(xact);
173: }
174:
175: /* Undo operation is a COMPENSATION log operation */
176: public int group() {
177: return super .group() | Loggable.COMPENSATION
178: | Loggable.RAWSTORE;
179: }
180:
181: public final ByteArray getPreparedLog() {
182: // should never ever write optional data because this implementation of
183: // the recovery system will never read this and pass this on to dome.
184: // Instead, the optional data of the undoOp will be used - since
185: // this.doMe can only call undoOP.undoMe, this has no use for any
186: // optional data.
187: return (ByteArray) null;
188: }
189:
190: public void restoreMe(Transaction xact, BasePage undoPage,
191: LogInstant CLRinstant, LimitObjectInput in) {
192: // Not undoable
193: if (SanityManager.DEBUG)
194: SanityManager
195: .THROWASSERT("cannot call restore me on PhysicalUndoOperation");
196: }
197:
198: /**
199: DEBUG: Print self.
200: */
201: public String toString() {
202: if (SanityManager.DEBUG) {
203: String str = "CLR (Physical Undo): " + super .toString();
204: if (undoOp != null)
205: str += "\n" + undoOp.toString();
206: else
207: str += "undo Operation not set";
208:
209: return str;
210: } else
211: return null;
212: }
213:
214: }
|