1 | /* |
2 | |
3 | Derby - Class org.apache.derby.impl.store.raw.xact.RowLocking3Escalate |
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 | |
21 | package org.apache.derby.impl.store.raw.xact; |
22 | |
23 | import org.apache.derby.iapi.services.locks.LockFactory; |
24 | import org.apache.derby.iapi.services.locks.Latch; |
25 | |
26 | import org.apache.derby.iapi.services.sanity.SanityManager; |
27 | |
28 | import org.apache.derby.iapi.store.raw.ContainerHandle; |
29 | import org.apache.derby.iapi.store.raw.ContainerLock; |
30 | import org.apache.derby.iapi.store.raw.RecordHandle; |
31 | import org.apache.derby.iapi.store.raw.Transaction; |
32 | |
33 | import org.apache.derby.iapi.error.StandardException; |
34 | |
35 | |
36 | /** |
37 | A locking policy that implements row level locking with isolation degree 3. |
38 | |
39 | @see org.apache.derby.iapi.store.raw.LockingPolicy |
40 | */ |
41 | public class RowLocking3Escalate extends ContainerLocking3 |
42 | { |
43 | protected RowLocking3Escalate(LockFactory lf) |
44 | { |
45 | super(lf); |
46 | } |
47 | |
48 | /** |
49 | * Escalates Row Locking 3 to Container Locking 3. |
50 | * <p> |
51 | * This call is made by code which tracks the number of locks on a |
52 | * container. When the number of locks exceeds the escalate threshold |
53 | * the caller creates this new locking policy, calls lockContainer(), |
54 | * and substitues it for the old locking policy. The lockContainer call |
55 | * determines which table lock to get (S or X), gets that table lock, and |
56 | * then releases the row locks on the table. |
57 | * |
58 | * It is assumed that this is called on a open container for lock only. |
59 | * <p> |
60 | * |
61 | * @param t Transaction to associate lock with. |
62 | * @param container Container to lock. |
63 | * @param waitForLock Ignored - will never wait for a lock. |
64 | * @param forUpdate Ignored, mode determined from current lock state. |
65 | * |
66 | * @return true if the lock was obtained, false if it wasn't. |
67 | * False should only be returned if the waitForLock policy was set to |
68 | * "false," and the lock was unavailable. |
69 | * |
70 | * @exception StandardException Standard exception policy. |
71 | **/ |
72 | public boolean lockContainer( |
73 | Transaction t, |
74 | ContainerHandle container, |
75 | boolean waitForLock, |
76 | boolean forUpdate) |
77 | throws StandardException |
78 | { |
79 | forUpdate = false; |
80 | |
81 | // If an IX lock exists then escalate to X table lock, else escalate |
82 | // to S table lock. |
83 | if (lf.isLockHeld( |
84 | t.getCompatibilitySpace(), t, |
85 | container.getId(), ContainerLock.CIX)) |
86 | { |
87 | forUpdate = true; |
88 | } |
89 | |
90 | // Get the new X or S table lock. |
91 | boolean gotLock = |
92 | super.lockContainer(t, container, waitForLock, forUpdate); |
93 | |
94 | if (!gotLock) |
95 | return false; |
96 | |
97 | // now remove all matching ROW locks, this is done using the special |
98 | // EscalateContainerKey() class which through the Matchable interface |
99 | // only matches row locks of this container. |
100 | lf.unlockGroup( |
101 | t.getCompatibilitySpace(), t, |
102 | new EscalateContainerKey(container.getId())); |
103 | |
104 | if (SanityManager.DEBUG) |
105 | { |
106 | SanityManager.ASSERT( |
107 | lf.isLockHeld( |
108 | t.getCompatibilitySpace(), t, |
109 | container.getId(), |
110 | (forUpdate ? ContainerLock.CX : ContainerLock.CS)), |
111 | "Covering table lock (" + |
112 | (forUpdate ? ContainerLock.CX : ContainerLock.CS) + |
113 | " is not held after lock escalation."); |
114 | } |
115 | |
116 | return true; |
117 | } |
118 | } |