001: /*
002:
003: Derby - Class org.apache.derby.impl.store.raw.xact.ContainerLocking2
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:
027: import org.apache.derby.iapi.store.raw.ContainerHandle;
028: import org.apache.derby.iapi.store.raw.ContainerLock;
029: import org.apache.derby.iapi.store.raw.Transaction;
030:
031: import org.apache.derby.iapi.error.StandardException;
032:
033: /**
034: A locking policy that implements container level locking with
035: isolation degree 2.
036:
037: @see org.apache.derby.iapi.store.raw.LockingPolicy
038: */
039: public class ContainerLocking2 extends NoLocking {
040:
041: private final LockFactory lf;
042:
043: protected ContainerLocking2() {
044: this .lf = null;
045: }
046:
047: protected ContainerLocking2(LockFactory lf) {
048: this .lf = lf;
049: }
050:
051: /**
052: Obtain a Container shared or exclusive lock until
053: the end of the nested transaction.
054:
055: @exception StandardException Standard Cloudscape error policy
056: */
057: public boolean lockContainer(Transaction t,
058: ContainerHandle container, boolean waitForLock,
059: boolean forUpdate) throws StandardException {
060: Object qualifier = forUpdate ? ContainerLock.CX
061: : ContainerLock.CS;
062:
063: // for cursor stability put read locks on a separate lock chain, which
064: // will be released when the container is unlocked.
065: Object group = forUpdate ? t : container.getUniqueId();
066:
067: return (lf.lockObject(t.getCompatibilitySpace(), group,
068: container.getId(), qualifier,
069: waitForLock ? C_LockFactory.TIMED_WAIT
070: : C_LockFactory.NO_WAIT));
071: }
072:
073: /**
074: * Unlock read locks.
075: * <p>
076: * In Cursor stability release all read locks obtained. unlockContainer()
077: * will be called when the container is closed.
078: * <p>
079: *
080: * @param t The transaction to associate the lock with.
081: * @param container Container to unlock.
082: *
083: **/
084: public void unlockContainer(Transaction t, ContainerHandle container) {
085: // Only release read locks before end of transaction in level 2.
086: if (container.isReadOnly()) {
087: lf.unlockGroup(t.getCompatibilitySpace(), container
088: .getUniqueId());
089: }
090: }
091:
092: public int getMode() {
093: return MODE_CONTAINER;
094: }
095:
096: /*
097: ** We can inherit all the others methods of NoLocking since we hold the
098: ** container lock until the end of transaction, and we don't obtain row
099: ** locks.
100: */
101: }
|