001: /*
002:
003: Derby - Class org.apache.derby.impl.store.raw.xact.RowLocking3Escalate
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.Latch;
026:
027: import org.apache.derby.iapi.services.sanity.SanityManager;
028:
029: import org.apache.derby.iapi.store.raw.ContainerHandle;
030: import org.apache.derby.iapi.store.raw.ContainerLock;
031: import org.apache.derby.iapi.store.raw.RecordHandle;
032: import org.apache.derby.iapi.store.raw.Transaction;
033:
034: import org.apache.derby.iapi.error.StandardException;
035:
036: /**
037: A locking policy that implements row level locking with isolation degree 3.
038:
039: @see org.apache.derby.iapi.store.raw.LockingPolicy
040: */
041: public class RowLocking3Escalate extends ContainerLocking3 {
042: protected RowLocking3Escalate(LockFactory lf) {
043: super (lf);
044: }
045:
046: /**
047: * Escalates Row Locking 3 to Container Locking 3.
048: * <p>
049: * This call is made by code which tracks the number of locks on a
050: * container. When the number of locks exceeds the escalate threshold
051: * the caller creates this new locking policy, calls lockContainer(),
052: * and substitues it for the old locking policy. The lockContainer call
053: * determines which table lock to get (S or X), gets that table lock, and
054: * then releases the row locks on the table.
055: *
056: * It is assumed that this is called on a open container for lock only.
057: * <p>
058: *
059: * @param t Transaction to associate lock with.
060: * @param container Container to lock.
061: * @param waitForLock Ignored - will never wait for a lock.
062: * @param forUpdate Ignored, mode determined from current lock state.
063: *
064: * @return true if the lock was obtained, false if it wasn't.
065: * False should only be returned if the waitForLock policy was set to
066: * "false," and the lock was unavailable.
067: *
068: * @exception StandardException Standard exception policy.
069: **/
070: public boolean lockContainer(Transaction t,
071: ContainerHandle container, boolean waitForLock,
072: boolean forUpdate) throws StandardException {
073: forUpdate = false;
074:
075: // If an IX lock exists then escalate to X table lock, else escalate
076: // to S table lock.
077: if (lf.isLockHeld(t.getCompatibilitySpace(), t, container
078: .getId(), ContainerLock.CIX)) {
079: forUpdate = true;
080: }
081:
082: // Get the new X or S table lock.
083: boolean gotLock = super .lockContainer(t, container,
084: waitForLock, forUpdate);
085:
086: if (!gotLock)
087: return false;
088:
089: // now remove all matching ROW locks, this is done using the special
090: // EscalateContainerKey() class which through the Matchable interface
091: // only matches row locks of this container.
092: lf.unlockGroup(t.getCompatibilitySpace(), t,
093: new EscalateContainerKey(container.getId()));
094:
095: if (SanityManager.DEBUG) {
096: SanityManager.ASSERT(lf.isLockHeld(t
097: .getCompatibilitySpace(), t, container.getId(),
098: (forUpdate ? ContainerLock.CX : ContainerLock.CS)),
099: "Covering table lock ("
100: + (forUpdate ? ContainerLock.CX
101: : ContainerLock.CS)
102: + " is not held after lock escalation.");
103: }
104:
105: return true;
106: }
107: }
|