001: /*
002:
003: Derby - Class org.apache.derby.impl.store.raw.xact.RowLocking3
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.xact;
023:
024: import org.apache.derby.iapi.services.locks.LockFactory;
025: import org.apache.derby.iapi.services.locks.C_LockFactory;
026: import org.apache.derby.iapi.services.locks.Latch;
027:
028: import org.apache.derby.iapi.services.sanity.SanityManager;
029:
030: import org.apache.derby.iapi.store.raw.ContainerHandle;
031: import org.apache.derby.iapi.store.raw.ContainerLock;
032: import org.apache.derby.iapi.store.raw.RecordHandle;
033: import org.apache.derby.iapi.store.raw.RowLock;
034: import org.apache.derby.iapi.store.raw.Transaction;
035: import org.apache.derby.iapi.store.raw.LockingPolicy;
036:
037: import org.apache.derby.iapi.error.StandardException;
038:
039: /**
040: A locking policy that implements row level locking with isolation degree 3.
041:
042: @see org.apache.derby.iapi.store.raw.LockingPolicy
043: */
044: public class RowLocking3 extends NoLocking {
045: // no locking has no state, so it's safe to hold
046: // it as a static
047: private static final LockingPolicy NO_LOCK = new NoLocking();
048:
049: protected final LockFactory lf;
050:
051: protected RowLocking3(LockFactory lf) {
052: this .lf = lf;
053: }
054:
055: /**
056: * Get type of lock to get while reading data.
057: * <p>
058: * This routine is provided so that class's like RowLockingRR can
059: * override just this routine to get RS2 locks vs RS3 locks, and still
060: * reuse all the other code in this class.
061: * <p>
062: *
063: * @return The lock type of a shared lock for this locking policy.
064: **/
065: protected RowLock getReadLockType() {
066: return (RowLock.RS3);
067: }
068:
069: /**
070: * Get type of lock to get while requesting "update" lock.
071: * <p>
072: * This routine is provided so that class's like RowLockingRR can
073: * override just this routine to get RU2 locks vs RU3 locks, and still
074: * reuse all the other code in this class.
075: * <p>
076: *
077: * @return The lock type of a shared lock for this locking policy.
078: **/
079: protected RowLock getUpdateLockType() {
080: return (RowLock.RU3);
081: }
082:
083: /**
084: * Get type of lock to get while writing data.
085: * <p>
086: * This routine is provided so that class's like RowLockingRR can
087: * override just this routine to get RX2 locks vs RX3 locks, and still
088: * reuse all the other code in this class.
089: * <p>
090: *
091: * @return The lock type of a shared lock for this locking policy.
092: **/
093: protected RowLock getWriteLockType() {
094: return (RowLock.RX3);
095: }
096:
097: /**
098: * Obtain container level intent lock.
099: * <p>
100: * This implementation of row locking is 2 level, ie. table and row locking.
101: * It will interact correctly with tables opened with ContainerLocking3
102: * locking mode.
103: * <p>
104: * Updater's will get table level IX locks, and X row locks.
105: * <p>
106: * Reader's will get table level IS locks, and S row locks.
107: *
108: * @param t Transaction to associate lock with.
109: * @param container Container to lock.
110: * @param waitForLock Should lock request wait until granted?
111: * @param forUpdate Should container be locked for update, or read?
112: *
113: * @return true if the lock was obtained, false if it wasn't.
114: * False should only be returned if the waitForLock policy was set to
115: * "false," and the lock was unavailable.
116: *
117: * @exception StandardException Standard exception policy.
118: **/
119: public boolean lockContainer(Transaction t,
120: ContainerHandle container, boolean waitForLock,
121: boolean forUpdate) throws StandardException {
122: Object qualifier = forUpdate ? ContainerLock.CIX
123: : ContainerLock.CIS;
124:
125: boolean gotLock = lf.lockObject(t.getCompatibilitySpace(), t,
126: container.getId(), qualifier,
127: waitForLock ? C_LockFactory.TIMED_WAIT
128: : C_LockFactory.NO_WAIT);
129:
130: if (gotLock) {
131: // look for covering table locks
132: // CIS is covered by CX or CS
133: // CIX is covered by CX
134:
135: if (lf.isLockHeld(t.getCompatibilitySpace(), t, container
136: .getId(), ContainerLock.CX)
137: || ((!forUpdate) && lf.isLockHeld(t
138: .getCompatibilitySpace(), t, container
139: .getId(), ContainerLock.CS))) {
140:
141: container.setLockingPolicy(NO_LOCK);
142: }
143: }
144:
145: return gotLock;
146:
147: }
148:
149: /**
150: * Obtain lock on record being read.
151: * <p>
152: * Assumes that a table level IS has been acquired. Will acquire a Shared
153: * or Update lock on the row, depending on the "forUpdate" parameter.
154: * <p>
155: *
156: * @param t The transaction to associate the lock with.
157: * @param record The record to be locked.
158: * @param waitForLock Should lock request wait until granted?
159: * @param forUpdate Whether to open for read or write access.
160: *
161: * @return true if the lock was granted, false if waitForLock was false
162: * and the lock could not be granted.
163: *
164: * @exception StandardException Standard exception policy.
165: **/
166: public boolean lockRecordForRead(Transaction t,
167: ContainerHandle container_handle, RecordHandle record,
168: boolean waitForLock, boolean forUpdate)
169: throws StandardException {
170: // RESOLVE - Did I do the right thing with the "forUpdate" variable.
171:
172: // For now just lock the row in Shared mode.
173: Object qualifier = forUpdate ? getUpdateLockType()
174: : getReadLockType();
175:
176: return (lf.lockObject(t.getCompatibilitySpace(), t, record,
177: qualifier, waitForLock ? C_LockFactory.TIMED_WAIT
178: : C_LockFactory.NO_WAIT));
179: }
180:
181: /**
182: * Obtain lock on record being read while holding a latch.
183: * <p>
184: * Assumes that a table level IS has been acquired. Will acquire a Shared
185: * or Update lock on the row, depending on the "forUpdate" parameter.
186: * <p>
187: *
188: * @param latch The latch being held.
189: * @param record The record to be locked.
190: * @param forUpdate Whether to open for read or write access.
191: *
192: * @exception StandardException Standard exception policy.
193: **/
194: public void lockRecordForRead(Latch latch, RecordHandle record,
195: boolean forUpdate) throws StandardException {
196: // RESOLVE - Did I do the right thing with the "forUpdate" variable.
197:
198: // For now just lock the row in Shared mode.
199: Object qualifier = forUpdate ? getUpdateLockType()
200: : getReadLockType();
201:
202: lf.lockObject(latch.getCompatabilitySpace(), record, qualifier,
203: C_LockFactory.TIMED_WAIT, latch);
204: }
205:
206: /**
207: * Obtain lock on record being written.
208: * <p>
209: * Assumes that a table level IX has been acquired. Will acquire an
210: * Exclusive (X) lock on the row.
211: * <p>
212: *
213: * @param t transaction to associate the lock with.
214: * @param record The record to be locked.
215: * @param lockForInsertPreviousKey Lock is for a previous key of a insert.
216: * @param waitForLock Should lock request wait until granted?
217: *
218: * @return true if the lock was granted, false if waitForLock was false
219: * and the lock could not be granted.
220: *
221: * @exception StandardException Standard exception policy.
222: **/
223: public boolean zeroDurationLockRecordForWrite(Transaction t,
224: RecordHandle record, boolean lockForInsertPreviousKey,
225: boolean waitForLock) throws StandardException {
226: return (lf.zeroDurationlockObject(t.getCompatibilitySpace(),
227: record, (lockForInsertPreviousKey ? RowLock.RIP
228: : getWriteLockType()),
229: waitForLock ? C_LockFactory.TIMED_WAIT
230: : C_LockFactory.NO_WAIT));
231: }
232:
233: /**
234: * Obtain lock on record being written.
235: * <p>
236: * Assumes that a table level IX has been acquired. Will acquire an
237: * Exclusive (X) lock on the row.
238: * <p>
239: *
240: * @param t The transaction to associate the lock with.
241: * @param record The record to be locked.
242: * @param lockForInsert Lock is for an insert.
243: * @param waitForLock Should lock request wait until granted?
244: *
245: * @return true if the lock was granted, false if waitForLock was false
246: * and the lock could not be granted.
247: *
248: * @exception StandardException Standard exception policy.
249: **/
250: public boolean lockRecordForWrite(Transaction t,
251: RecordHandle record, boolean lockForInsert,
252: boolean waitForLock) throws StandardException {
253: return (lf.lockObject(t.getCompatibilitySpace(), t, record,
254: lockForInsert ? RowLock.RI : getWriteLockType(),
255: waitForLock ? C_LockFactory.TIMED_WAIT
256: : C_LockFactory.NO_WAIT));
257: }
258:
259: /**
260: * Obtain lock on record being written while holding a latch.
261: * <p>
262: * Assumes that a table level IX has been acquired. Will acquire an
263: * Exclusive (X) lock on the row.
264: * <p>
265: *
266: * @param latch The latch being held
267: * @param record The record to be locked.
268: *
269: * @exception StandardException Standard exception policy.
270: **/
271: public void lockRecordForWrite(Latch latch, RecordHandle record)
272: throws StandardException {
273: lf.lockObject(latch.getCompatabilitySpace(), record,
274: getWriteLockType(), C_LockFactory.TIMED_WAIT, latch);
275: }
276:
277: public int getMode() {
278: return MODE_RECORD;
279: }
280:
281: /*
282: ** We can inherit all the others methods of NoLocking since we hold the
283: ** container lock and row locks until the end of transaction.
284: */
285: }
|