View Javadoc

1   package org.apache.ojb.odmg.locking;
2   
3   /* Copyright 2002-2005 The Apache Software Foundation
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License");
6    * you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  import org.apache.ojb.odmg.TransactionImpl;
19  
20  import java.util.Collection;
21  
22  /**
23   * The implementation of the Repeatable Reads Locking strategy.
24   * Locks are obtained for reading and modifying the database.
25   * Locks on all modified objects are held until EOT.
26   * Locks obtained for reading data are held until EOT.
27   * Allows:
28   * Phantom Reads
29   *
30   * @author Thomas Mahler & David Dixon-Peugh
31   */
32  public class RepeatableReadStrategy extends AbstractLockStrategy
33  {
34      /**
35       * acquire a read lock on Object obj for Transaction tx.
36       * @param tx the transaction requesting the lock
37       * @param obj the Object to be locked
38       * @return true if successful, else false
39       *
40       */
41      public boolean readLock(TransactionImpl tx, Object obj)
42      {
43          LockEntry writer = getWriter(obj);
44          if (writer == null)
45          {
46              if (addReader(tx, obj))
47                  return true;
48              else
49                  return readLock(tx, obj);
50          }
51          if (writer.isOwnedBy(tx))
52          {
53              return true;    // If I'm the writer, I can read.
54          }
55          else
56              return false;
57  
58      }
59  
60      /**
61       * acquire a write lock on Object obj for Transaction tx.
62       * @param tx the transaction requesting the lock
63       * @param obj the Object to be locked
64       * @return true if successful, else false
65       *
66       */
67      public boolean writeLock(TransactionImpl tx, Object obj)
68      {
69          LockEntry writer = getWriter(obj);
70          Collection readers = getReaders(obj);
71          if (writer == null)
72          {
73              if (readers.size() == 0)
74              {
75                  if (setWriter(tx, obj))
76                      return true;
77                  else
78                      return writeLock(tx, obj);
79              }
80  
81              else if (readers.size() == 1)
82              {
83                  if (((LockEntry) readers.iterator().next()).isOwnedBy(tx))
84                      return upgradeLock(tx, obj);
85              }
86          }
87          else if (writer.isOwnedBy(tx))
88          {
89              return true;    // If I'm the writer, then I can write.
90          }
91          return false;
92      }
93  
94  
95      /**
96       * acquire a lock upgrade (from read to write) lock on Object obj for Transaction tx.
97       * @param tx the transaction requesting the lock
98       * @param obj the Object to be locked
99       * @return true if successful, else false
100      *
101      */
102     public boolean upgradeLock(TransactionImpl tx, Object obj)
103     {
104         LockEntry writer = getWriter(obj);
105         if (writer == null)
106         {
107             Collection readers = this.getReaders(obj);
108             if (readers.size() == 1)
109             {
110                 LockEntry reader = (LockEntry) readers.iterator().next();
111                 if (reader.isOwnedBy(tx))
112                 {
113                     if (upgradeLock(reader))
114                         return true;
115                     else
116                         return upgradeLock(tx, obj);
117                 }
118             }
119             else if (readers.size() == 0)
120             {
121                 if (setWriter(tx, obj))
122                     return true;
123                 else
124                     return upgradeLock(tx, obj);
125             }
126 
127 
128         }
129         else if (writer.isOwnedBy(tx))
130         {
131             return true;    // If I already have Write, then I've upgraded.
132         }
133 
134         return false;
135     }
136 
137     /**
138      * release a lock on Object obj for Transaction tx.
139      * @param tx the transaction releasing the lock
140      * @param obj the Object to be unlocked
141      * @return true if successful, else false
142      *
143      */
144     public boolean releaseLock(TransactionImpl tx, Object obj)
145     {
146         LockEntry writer = getWriter(obj);
147         if (writer != null && writer.isOwnedBy(tx))
148         {
149             removeWriter(writer);
150             return true;
151         }
152         if (hasReadLock(tx, obj))
153         {
154             removeReader(tx, obj);
155             return true;
156         }
157         return false;
158     }
159 
160     /**
161      * checks whether the specified Object obj is read-locked by Transaction tx.
162      * @param tx the transaction
163      * @param obj the Object to be checked
164      * @return true if lock exists, else false
165      */
166     public boolean checkRead(TransactionImpl tx, Object obj)
167     {
168         if (hasReadLock(tx, obj))
169         {
170             return true;
171         }
172         LockEntry writer = getWriter(obj);
173         if (writer != null && writer.isOwnedBy(tx))
174         {
175             return true;
176         }
177         else
178             return false;
179     }
180 
181     /**
182      * checks whether the specified Object obj is write-locked by Transaction tx.
183      * @param tx the transaction
184      * @param obj the Object to be checked
185      * @return true if lock exists, else false
186      */
187     public boolean checkWrite(TransactionImpl tx, Object obj)
188     {
189         LockEntry writer = getWriter(obj);
190         return (writer != null && writer.isOwnedBy(tx));
191     }
192 }