KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > store > raw > xact > RowLocking2


1 /*
2
3    Derby - Class org.apache.derby.impl.store.raw.xact.RowLocking2
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.impl.store.raw.xact;
23
24 import org.apache.derby.iapi.services.locks.LockFactory;
25 import org.apache.derby.iapi.services.locks.C_LockFactory;
26 import org.apache.derby.iapi.services.locks.Latch;
27
28 import org.apache.derby.iapi.services.sanity.SanityManager;
29
30 import org.apache.derby.iapi.store.raw.ContainerHandle;
31 import org.apache.derby.iapi.store.raw.ContainerLock;
32 import org.apache.derby.iapi.store.raw.LockingPolicy;
33 import org.apache.derby.iapi.store.raw.RecordHandle;
34 import org.apache.derby.iapi.store.raw.RowLock;
35 import org.apache.derby.iapi.store.raw.Transaction;
36
37 import org.apache.derby.iapi.error.StandardException;
38
39
40 /**
41     A locking policy that implements row level locking with isolation degree 2.
42
43     The approach is to place all "write" container and row locks on the
44     transaction group lock list. Locks on this group will last until end
45     of transaction. All "read" container and row locks will be placed
46     on a group list, key'd by the ContainerId of the lock. Locks on this
47     list will either be released explicitly by the caller, or will be released
48     as a group when the unlockContainer() call is made.
49
50     Note that write operations extend from the RowLocking3 implementations.
51
52     @see org.apache.derby.iapi.store.raw.LockingPolicy
53 */

54 public class RowLocking2 extends RowLockingRR
55 {
56     // no locking has no state, so it's safe to hold
57
// it as a static
58
private static final LockingPolicy NO_LOCK = new NoLocking();
59
60     protected RowLocking2(LockFactory lf)
61     {
62         super(lf);
63     }
64
65     /**
66      * Obtain container level intent lock.
67      * <p>
68      * This implementation of row locking is 2 level, ie. table and row locking.
69      * It will interact correctly with tables opened with ContainerLocking3
70      * locking mode.
71      * <p>
72      * Updater's will get table level IX locks, and X row locks.
73      * <p>
74      * Reader's will get table level IS locks, and S row locks.
75      * <p>
76      * Read locks are put in a separate "group" from the transaction, so that
77      * when the container is closed it can release these read locks.
78      *
79      * @param t Transaction to associate lock with.
80      * @param container Container to lock.
81      * @param waitForLock Should lock request wait until granted?
82      * @param forUpdate Should container be locked for update, or read?
83      *
84      * @return true if the lock was obtained, false if it wasn't.
85      * False should only be returned if the waitForLock policy was set to
86      * "false," and the lock was unavailable.
87      *
88      * @exception StandardException Standard exception policy.
89      **/

90     public boolean lockContainer(
91     Transaction t,
92     ContainerHandle container,
93     boolean waitForLock,
94     boolean forUpdate)
95         throws StandardException
96     {
97         Object JavaDoc qualifier = forUpdate ? ContainerLock.CIX : ContainerLock.CIS;
98
99         // for cursor stability put read locks on a separate lock chain, which
100
// will be released when the container is unlocked.
101
Object JavaDoc group =
102             forUpdate ? ((Object JavaDoc) t) : ((Object JavaDoc) container.getUniqueId());
103
104         boolean gotLock =
105             lf.lockObject(
106                 t.getCompatibilitySpace(), group, container.getId(), qualifier,
107                 waitForLock ? C_LockFactory.TIMED_WAIT : C_LockFactory.NO_WAIT);
108
109         if (gotLock)
110         {
111             // look for covering table locks
112
// CIS and CIX is covered by CX
113
// In that case move the lock to the transaction list from the
114
// container list, as the null locking policy will do nothing in
115
// unlockContainer().
116
//
117

118
119             if (lf.isLockHeld(t.getCompatibilitySpace(), t, container.getId(),
120                               ContainerLock.CX))
121             {
122                 //release any container group locks becuase CX container lock will cover everthing.
123
lf.unlockGroup(t.getCompatibilitySpace(), container.getUniqueId());
124                 container.setLockingPolicy(NO_LOCK);
125             }else if ((!forUpdate) &&
126                      lf.isLockHeld(t.getCompatibilitySpace(), t, container.getId(), ContainerLock.CS))
127             {
128                 // move locks from container group to transaction group.
129
lf.transfer(t.getCompatibilitySpace(), group, t);
130                 container.setLockingPolicy(NO_LOCK);
131             }
132         }
133
134         return gotLock;
135     }
136
137
138     /**
139      * Obtain lock on record being read.
140      * <p>
141      * Assumes that a table level IS has been acquired. Will acquire a Shared
142      * or Update lock on the row, depending on the "forUpdate" parameter.
143      * <p>
144      * Read lock will be placed on separate group from transaction.
145      *
146      * @param t The transaction to associate the lock with.
147      * @param record The record to be locked.
148      * @param waitForLock Should lock request wait until granted?
149      * @param forUpdate Whether to open for read or write access.
150      *
151      * @return true if the lock was granted, false if waitForLock was false
152      * and the lock could not be granted.
153      *
154      * @exception StandardException Standard exception policy.
155      **/

156     public boolean lockRecordForRead(
157     Transaction t,
158     ContainerHandle container_handle,
159     RecordHandle record,
160     boolean waitForLock,
161     boolean forUpdate)
162         throws StandardException
163     {
164         Object JavaDoc qualifier = forUpdate ? RowLock.RU2 : RowLock.RS2;
165
166         return(
167             lf.lockObject(
168                 t.getCompatibilitySpace(),
169                 container_handle.getUniqueId(),
170                 record,
171                 qualifier,
172                 waitForLock ?
173                     C_LockFactory.TIMED_WAIT : C_LockFactory.NO_WAIT));
174     }
175
176     /**
177      * Obtain lock on record being read while holding a latch.
178      * <p>
179      * Assumes that a table level IS has been acquired. Will acquire a Shared
180      * or Update lock on the row, depending on the "forUpdate" parameter.
181      * <p>
182      *
183      * @param latch The latch being held.
184      * @param record The record to be locked.
185      * @param forUpdate Whether to open for read or write access.
186      *
187      * @exception StandardException Standard exception policy.
188      **/

189     public void lockRecordForRead(
190     Latch latch,
191     RecordHandle record,
192     boolean forUpdate)
193         throws StandardException
194     {
195         // RESOLVE - Did I do the right thing with the "forUpdate" variable.
196
// RESOLVE (mikem) - looks like it needs work for update locks, and
197
// compatibility spaces.
198

199         Object JavaDoc qualifier = forUpdate ? RowLock.RU2 : RowLock.RS2;
200
201         lf.lockObject(
202             record.getContainerId(), record, qualifier,
203             C_LockFactory.TIMED_WAIT, latch);
204     }
205
206     public void unlockRecordAfterRead(
207     Transaction t,
208     ContainerHandle container_handle,
209     RecordHandle record,
210     boolean forUpdate,
211     boolean row_qualified)
212         throws StandardException
213     {
214         Object JavaDoc qualifier = forUpdate ? RowLock.RU2 : RowLock.RS2;
215
216         int count =
217             lf.unlock(
218                 t.getCompatibilitySpace(), container_handle.getUniqueId(),
219                 record, qualifier);
220
221         if (SanityManager.DEBUG)
222         {
223             // in the case of lock escalation the count could be 0.
224
if (!(count == 1 || count == 0))
225             {
226                 SanityManager.THROWASSERT(
227                 "count = " + count +
228                 "record.getContainerId() = " + record.getContainerId());
229             }
230         }
231     }
232
233     /**
234      * Unlock read locks.
235      * <p>
236      * In Cursor stability release all read locks obtained. unlockContainer()
237      * will be called when the container is closed.
238      * <p>
239      *
240      * @param t The transaction to associate the lock with.
241      * @param container_handle Container to unlock.
242      **/

243     public void unlockContainer(
244     Transaction t,
245     ContainerHandle container_handle)
246     {
247         // Only release read locks before end of transaction in level 2.
248
lf.unlockGroup(
249             t.getCompatibilitySpace(), container_handle.getUniqueId());
250     }
251 }
252
Popular Tags