1 | /* |
2 | |
3 | Derby - Class org.apache.derby.impl.store.raw.xact.RowLockingRR |
4 | |
5 | Copyright 2000, 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 | package org.apache.derby.impl.store.raw.xact; |
21 | |
22 | import org.apache.derby.iapi.services.locks.LockFactory; |
23 | import org.apache.derby.iapi.services.locks.C_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.LockingPolicy; |
31 | import org.apache.derby.iapi.store.raw.RecordHandle; |
32 | import org.apache.derby.iapi.store.raw.RowLock; |
33 | import org.apache.derby.iapi.store.raw.Transaction; |
34 | |
35 | import org.apache.derby.iapi.error.StandardException; |
36 | |
37 | |
38 | /** |
39 | A locking policy that implements row level locking with repeatable read |
40 | isolation. Since phantom protection with previous key locking is actually |
41 | handled by the upper level access methods, the only difference in repeatable |
42 | read is that read locks are of type RowLock.RS2. This type will not |
43 | conflict with a previous key insert lock. |
44 | |
45 | @see org.apache.derby.iapi.store.raw.LockingPolicy |
46 | */ |
47 | public class RowLockingRR extends RowLocking3 |
48 | { |
49 | |
50 | protected RowLockingRR(LockFactory lf) |
51 | { |
52 | super(lf); |
53 | } |
54 | |
55 | protected RowLock getReadLockType() |
56 | { |
57 | return(RowLock.RS2); |
58 | } |
59 | |
60 | protected RowLock getUpdateLockType() |
61 | { |
62 | return(RowLock.RU2); |
63 | } |
64 | |
65 | protected RowLock getWriteLockType() |
66 | { |
67 | return(RowLock.RX2); |
68 | } |
69 | |
70 | /** |
71 | * Unlock a record after it has been locked for read. |
72 | * <p> |
73 | * In repeatable read only unlock records which "did not qualify". For |
74 | * example in a query like "select * from foo where a = 1" on a table |
75 | * with no index it is only necessary to hold locks on rows where a=1, but |
76 | * in the process of finding those rows the system will get locks on other |
77 | * rows to verify they are committed before applying the qualifier. Those |
78 | * locks can be released under repeatable read isolation. |
79 | * <p> |
80 | * |
81 | * @exception StandardException Standard exception policy. |
82 | **/ |
83 | public void unlockRecordAfterRead( |
84 | Transaction t, |
85 | ContainerHandle container_handle, |
86 | RecordHandle record, |
87 | boolean forUpdate, |
88 | boolean row_qualified) |
89 | throws StandardException |
90 | { |
91 | if (!row_qualified) |
92 | { |
93 | Object qualifier = forUpdate ? RowLock.RU2 : RowLock.RS2; |
94 | |
95 | int count = |
96 | lf.unlock(t.getCompatibilitySpace(), t, record, qualifier); |
97 | |
98 | if (SanityManager.DEBUG) |
99 | { |
100 | // in the case of lock escalation the count could be 0. |
101 | if (!(count == 1 || count == 0)) |
102 | { |
103 | SanityManager.THROWASSERT( |
104 | "count = " + count + |
105 | "record.getContainerId() = " + record.getContainerId()); |
106 | } |
107 | } |
108 | } |
109 | } |
110 | |
111 | } |