EMMA Coverage Report (generated Wed Jun 28 22:15:27 PDT 2006)
[all classes][org.apache.derby.impl.store.raw.xact]

COVERAGE SUMMARY FOR SOURCE FILE [RowLocking2.java]

nameclass, %method, %block, %line, %
RowLocking2.java100% (1/1)86%  (6/7)81%  (135/166)85%  (22/26)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class RowLocking2100% (1/1)86%  (6/7)81%  (135/166)85%  (22/26)
<static initializer> 100% (1/1)100% (5/5)100% (1/1)
RowLocking2 (LockFactory): void 100% (1/1)100% (4/4)100% (2/2)
lockContainer (Transaction, ContainerHandle, boolean, boolean): boolean 100% (1/1)100% (75/75)100% (11/11)
lockRecordForRead (Latch, RecordHandle, boolean): void 0%   (0/1)0%   (0/17)0%   (0/3)
lockRecordForRead (Transaction, ContainerHandle, RecordHandle, boolean, boole... 100% (1/1)100% (21/21)100% (2/2)
unlockContainer (Transaction, ContainerHandle): void 100% (1/1)100% (8/8)100% (2/2)
unlockRecordAfterRead (Transaction, ContainerHandle, RecordHandle, boolean, b... 100% (1/1)61%  (22/36)80%  (4/5)

1/*
2 
3   Derby - Class org.apache.derby.impl.store.raw.xact.RowLocking2
4 
5   Copyright 1998, 2004 The Apache Software Foundation or its licensors, as applicable.
6 
7   Licensed under the Apache License, Version 2.0 (the "License");
8   you may not use this file except in compliance with the License.
9   You may obtain a copy of the License at
10 
11      http://www.apache.org/licenses/LICENSE-2.0
12 
13   Unless required by applicable law or agreed to in writing, software
14   distributed under the License is distributed on an "AS IS" BASIS,
15   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   See the License for the specific language governing permissions and
17   limitations under the License.
18 
19 */
20 
21package org.apache.derby.impl.store.raw.xact;
22 
23import org.apache.derby.iapi.services.locks.LockFactory;
24import org.apache.derby.iapi.services.locks.C_LockFactory;
25import org.apache.derby.iapi.services.locks.Latch;
26 
27import org.apache.derby.iapi.services.sanity.SanityManager;
28 
29import org.apache.derby.iapi.store.raw.ContainerHandle;
30import org.apache.derby.iapi.store.raw.ContainerLock;
31import org.apache.derby.iapi.store.raw.LockingPolicy;
32import org.apache.derby.iapi.store.raw.RecordHandle;
33import org.apache.derby.iapi.store.raw.RowLock;
34import org.apache.derby.iapi.store.raw.Transaction;
35 
36import org.apache.derby.iapi.error.StandardException;
37 
38 
39/**
40        A locking policy that implements row level locking with isolation degree 2.
41 
42    The approach is to place all "write" container and row locks on the 
43    transaction group lock list.  Locks on this group will last until end
44    of transaction.  All "read" container and row locks will be placed 
45    on a group list, key'd by the ContainerId of the lock.  Locks on this
46    list will either be released explicitly by the caller, or will be released
47    as a group when the unlockContainer() call is made.
48 
49    Note that write operations extend from the RowLocking3 implementations.
50 
51        @see org.apache.derby.iapi.store.raw.LockingPolicy
52*/
53public class RowLocking2 extends RowLockingRR
54{
55        // no locking has no state, so it's safe to hold
56        // it as a static
57        private static final LockingPolicy NO_LOCK = new NoLocking();
58 
59        protected RowLocking2(LockFactory lf) 
60    {
61                super(lf);
62        }
63 
64    /**
65     * Obtain container level intent lock.
66     * <p>
67     * This implementation of row locking is 2 level, ie. table and row locking.
68     * It will interact correctly with tables opened with ContainerLocking3
69     * locking mode.
70     * <p>
71     * Updater's will get table level IX locks, and X row locks.
72     * <p>
73     * Reader's will get table level IS locks, and S row locks.
74     * <p>
75     * Read locks are put in a separate "group" from the transaction, so that
76     * when the container is closed it can release these read locks.
77     *
78     * @param t            Transaction to associate lock with.
79     * @param container    Container to lock.
80     * @param waitForLock  Should lock request wait until granted?
81     * @param forUpdate    Should container be locked for update, or read?
82     *
83     * @return true if the lock was obtained, false if it wasn't. 
84     *   False should only be returned if the waitForLock policy was set to
85     *  "false," and the lock was unavailable.
86     *
87         * @exception  StandardException  Standard exception policy.
88     **/
89        public boolean lockContainer(
90    Transaction         t, 
91    ContainerHandle     container, 
92    boolean             waitForLock,
93    boolean             forUpdate)
94                throws StandardException 
95    {
96                Object qualifier = forUpdate ? ContainerLock.CIX : ContainerLock.CIS;
97 
98        // for cursor stability put read locks on a separate lock chain, which
99        // will be released when the container is unlocked.
100        Object group = 
101            forUpdate ? ((Object) t) : ((Object) container.getUniqueId());
102 
103                boolean gotLock = 
104            lf.lockObject(
105                t.getCompatibilitySpace(), group, container.getId(), qualifier,
106                waitForLock ? C_LockFactory.TIMED_WAIT : C_LockFactory.NO_WAIT);
107 
108                if (gotLock) 
109        {
110                        // look for covering table locks
111                        // CIS and CIX is covered by CX 
112            // In that case move the lock to the transaction list from the
113            // container list, as the null locking policy will do nothing in
114            // unlockContainer().
115            //
116 
117 
118                        if (lf.isLockHeld(t.getCompatibilitySpace(), t, container.getId(),
119                                                          ContainerLock.CX))
120                        {
121                                //release any container group locks becuase CX container lock will cover everthing.
122                                lf.unlockGroup(t.getCompatibilitySpace(), container.getUniqueId());
123                                container.setLockingPolicy(NO_LOCK);
124                        }else if ((!forUpdate) && 
125                                         lf.isLockHeld(t.getCompatibilitySpace(), t, container.getId(), ContainerLock.CS))
126            {
127                // move locks from container group to transaction group.
128                                lf.transfer(t.getCompatibilitySpace(), group, t);
129                                container.setLockingPolicy(NO_LOCK);
130                        }
131                }
132 
133                return gotLock;
134        }
135 
136 
137    /**
138     * Obtain lock on record being read.
139     * <p>
140     * Assumes that a table level IS has been acquired.  Will acquire a Shared
141     * or Update lock on the row, depending on the "forUpdate" parameter.
142     * <p>
143     * Read lock will be placed on separate group from transaction.
144     *
145     * @param t             The transaction to associate the lock with.
146     * @param record        The record to be locked.
147     * @param waitForLock   Should lock request wait until granted?
148     * @param forUpdate     Whether to open for read or write access.
149     *
150     * @return true if the lock was granted, false if waitForLock was false 
151     * and the lock could not be granted.
152     *
153         * @exception  StandardException  Standard exception policy.
154     **/
155        public boolean lockRecordForRead(
156    Transaction     t, 
157    ContainerHandle container_handle,
158    RecordHandle    record, 
159    boolean         waitForLock,
160    boolean         forUpdate)
161                throws StandardException
162        {
163                Object qualifier = forUpdate ? RowLock.RU2 : RowLock.RS2;
164 
165        return( 
166            lf.lockObject(
167                t.getCompatibilitySpace(), 
168                container_handle.getUniqueId(), 
169                record, 
170                qualifier,
171                waitForLock ? 
172                    C_LockFactory.TIMED_WAIT : C_LockFactory.NO_WAIT));
173        }
174 
175    /**
176     * Obtain lock on record being read while holding a latch.
177     * <p>
178     * Assumes that a table level IS has been acquired.  Will acquire a Shared
179     * or Update lock on the row, depending on the "forUpdate" parameter.
180     * <p>
181     *
182     * @param latch         The latch being held.
183     * @param record        The record to be locked.
184     * @param forUpdate     Whether to open for read or write access.
185     *
186         * @exception  StandardException  Standard exception policy.
187     **/
188        public void lockRecordForRead(
189    Latch                        latch, 
190    RecordHandle    record, 
191    boolean         forUpdate)
192                throws StandardException
193        {
194        // RESOLVE - Did I do the right thing with the "forUpdate" variable.
195        // RESOLVE (mikem) - looks like it needs work for update locks, and
196        //     compatibility spaces.
197 
198                Object qualifier = forUpdate ? RowLock.RU2 : RowLock.RS2;
199 
200        lf.lockObject(
201            record.getContainerId(), record, qualifier, 
202            C_LockFactory.TIMED_WAIT, latch);
203        }
204 
205        public void unlockRecordAfterRead(
206    Transaction     t, 
207    ContainerHandle container_handle,
208    RecordHandle    record, 
209    boolean         forUpdate,
210    boolean         row_qualified)
211        throws StandardException
212        {
213                Object qualifier = forUpdate ? RowLock.RU2 : RowLock.RS2;
214 
215        int count = 
216            lf.unlock(
217                t.getCompatibilitySpace(), container_handle.getUniqueId(), 
218                record, qualifier);
219 
220        if (SanityManager.DEBUG)
221        {
222            // in the case of lock escalation the count could be 0.
223            if (!(count == 1 || count == 0))
224                        {
225                                SanityManager.THROWASSERT(
226                "count = " + count +
227                "record.getContainerId() = " + record.getContainerId());
228                        }
229        }
230        }
231 
232    /**
233     * Unlock read locks.
234     * <p>
235     * In Cursor stability release all read locks obtained.  unlockContainer()
236     * will be called when the container is closed.
237     * <p>
238     *
239     * @param t                 The transaction to associate the lock with.
240     * @param container_handle  Container to unlock.
241     **/
242        public void unlockContainer(
243    Transaction     t, 
244    ContainerHandle container_handle)
245    {
246        // Only release read locks before end of transaction in level 2.
247        lf.unlockGroup(
248            t.getCompatibilitySpace(), container_handle.getUniqueId());
249        }
250}

[all classes][org.apache.derby.impl.store.raw.xact]
EMMA 2.0.5312 (C) Vladimir Roubtsov