001: /*
002:
003: Derby - Class org.apache.derby.impl.store.access.btree.index.B2IRowLockingRR
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.access.btree.index;
023:
024: import org.apache.derby.iapi.services.sanity.SanityManager;
025:
026: import org.apache.derby.iapi.error.StandardException;
027:
028: import org.apache.derby.iapi.store.access.conglomerate.TransactionManager;
029:
030: import org.apache.derby.iapi.store.access.ConglomerateController;
031: import org.apache.derby.iapi.types.RowLocation;
032: import org.apache.derby.iapi.store.access.TransactionController;
033:
034: import org.apache.derby.iapi.store.raw.FetchDescriptor;
035: import org.apache.derby.iapi.store.raw.LockingPolicy;
036: import org.apache.derby.iapi.store.raw.Page;
037: import org.apache.derby.iapi.store.raw.RecordHandle;
038: import org.apache.derby.iapi.store.raw.Transaction;
039:
040: import org.apache.derby.iapi.types.DataValueDescriptor;
041:
042: import org.apache.derby.impl.store.access.btree.BTree;
043: import org.apache.derby.impl.store.access.btree.BTreeLockingPolicy;
044: import org.apache.derby.impl.store.access.btree.BTreeRowPosition;
045: import org.apache.derby.impl.store.access.btree.ControlRow;
046: import org.apache.derby.impl.store.access.btree.LeafControlRow;
047: import org.apache.derby.impl.store.access.btree.OpenBTree;
048: import org.apache.derby.impl.store.access.btree.WaitError;
049:
050: /**
051:
052: **/
053:
054: class B2IRowLockingRR extends B2IRowLocking3 implements
055: BTreeLockingPolicy {
056:
057: /**************************************************************************
058: * Constructors for This class:
059: **************************************************************************
060: */
061: B2IRowLockingRR(Transaction rawtran, int lock_level,
062: LockingPolicy locking_policy,
063: ConglomerateController base_cc, OpenBTree open_btree) {
064: super (rawtran, lock_level, locking_policy, base_cc, open_btree);
065: }
066:
067: /**************************************************************************
068: * Public Methods of This class:
069: **************************************************************************
070: */
071:
072: /**
073: * Lock a row as part of doing the scan.
074: * <p>
075: * Lock the row at the given slot (or the previous row if slot is 0).
076: * Get the scan lock on the page if "request_scan_lock" is true.
077: * <p>
078: * If this routine returns true all locks were acquired while maintaining
079: * the latch on leaf. If this routine returns false, locks may or may
080: * not have been acquired, and the routine should be called again after
081: * the client has researched the tree to reget the latch on the
082: * appropriate page.
083: * (p>
084: * As a side effect stores the value of the record handle of the current
085: * scan lock.
086: *
087: * @return Whether locks were acquired without releasing latch on leaf.
088: *
089: * @param open_btree The open_btree to associate latches with -
090: * used if routine has to scan backward.
091: * @param btree the conglomerate info.
092: * @param pos The position of the row to lock.
093: * @param request_scan_lock Whether to request the page scan lock, should
094: * only be requested once per page in the scan.
095: * @param lock_template A scratch area to use to read in rows.
096: * @param previous_key_lock Is this a previous key lock call?
097: * @param forUpdate Is the scan for update or for read only.
098: *
099: * @exception StandardException Standard exception policy.
100: **/
101: public boolean lockScanRow(OpenBTree open_btree, BTree btree,
102: BTreeRowPosition pos, boolean request_scan_lock,
103: FetchDescriptor lock_fetch_desc,
104: DataValueDescriptor[] lock_template,
105: RowLocation lock_row_loc, boolean previous_key_lock,
106: boolean forUpdate, int lock_operation)
107: throws StandardException {
108: // don't request row lock if this a previous key lock request, previous
109: // key lock is not required in isolation level 2.
110: return (_lockScanRow(open_btree,
111: btree,
112: pos,
113: !previous_key_lock, // request row lock iff not prev key lock
114: request_scan_lock, lock_fetch_desc, lock_template,
115: lock_row_loc, previous_key_lock, forUpdate,
116: lock_operation));
117: }
118:
119: /**
120: * Unlock a record after it has been locked for read.
121: * <p>
122: * In repeatable read only unlock records which "did not qualify". For
123: * example in a query like "select * from foo where a = 1" on a table
124: * with no index it is only necessary to hold locks on rows where a=1, but
125: * in the process of finding those rows the system will get locks on other
126: * rows to verify they are committed before applying the qualifier. Those
127: * locks can be released under repeatable read isolation.
128: * <p>
129: * if it is forUpdate then get S lock and release U lock, else there is
130: * nothing to do in serializable - we keep the S locks until end of
131: * transaction.
132: *
133: * @param forUpdate Is the scan for update or for read only.
134: *
135: **/
136: public void unlockScanRecordAfterRead(BTreeRowPosition pos,
137: boolean forUpdate) throws StandardException {
138: if (!pos.current_rh_qualified) {
139: if (SanityManager.DEBUG) {
140: SanityManager.ASSERT(pos.current_leaf != null,
141: "leaf is null");
142:
143: SanityManager.ASSERT(pos.current_lock_row_loc != null,
144: "row_loc is null");
145: }
146:
147: base_cc.unlockRowAfterRead(pos.current_lock_row_loc,
148: forUpdate, pos.current_rh_qualified);
149: }
150: }
151: }
|