001    package org.apache.ojb.odmg.locking;
002    
003    /* Copyright 2002-2005 The Apache Software Foundation
004     *
005     * Licensed under the Apache License, Version 2.0 (the "License");
006     * you may not use this file except in compliance with the License.
007     * You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    import org.apache.ojb.odmg.TransactionImpl;
019    
020    /**
021     * The implementation of the Commited Reads Locking stra
022     * ReadCommitted - Reads and Writes require locks.
023     *
024     * Locks are acquired for reading and modifying the database.
025     * Locks are released after reading but locks on modified objects
026     * are held until EOT.
027     *
028     * Allows:
029     * Non-Repeatable Reads
030     * Phantom Readstegy.
031     *
032     * @author Thomas Mahler & David Dixon-Peugh
033     */
034    public class ReadCommittedStrategy extends AbstractLockStrategy
035    {
036    
037        /**
038         * acquire a read lock on Object obj for Transaction tx.
039         * @param tx the transaction requesting the lock
040         * @param obj the Object to be locked
041         * @return true if successful, else false
042         *
043         */
044        public boolean readLock(TransactionImpl tx, Object obj)
045        {
046    
047            LockEntry writer = getWriter(obj);
048            if (writer == null)
049            {
050                addReader(tx, obj);
051                // if there has been a successful write locking, try again
052                if (getWriter(obj) == null)
053                    return true;
054                else
055                {
056                    removeReader(tx, obj);
057                    return readLock(tx, obj);
058                }
059            }
060            if (writer.isOwnedBy(tx))
061            {
062                return true;    // If I'm the writer, I can read.
063            }
064            else
065            {
066                return false;
067            }
068        }
069    
070        /**
071         * acquire a write lock on Object obj for Transaction tx.
072         * @param tx the transaction requesting the lock
073         * @param obj the Object to be locked
074         * @return true if successful, else false
075         *
076         */
077        public boolean writeLock(TransactionImpl tx, Object obj)
078        {
079            LockEntry writer = getWriter(obj);
080            // if there is no writer yet we can try to get the global write lock
081            if (writer == null)
082            {
083                // if lock could be acquired return true
084                if (setWriter(tx, obj))
085                    return true;
086                // else try again
087                else
088                    return writeLock(tx, obj);
089            }
090            if (writer.isOwnedBy(tx))
091            {
092                return true;    // If I'm the writer, then I can write.
093            }
094    
095            return false;
096        }
097    
098        /**
099         * acquire a lock upgrade (from read to write) lock on Object obj for Transaction tx.
100         * @param tx the transaction requesting the lock
101         * @param obj the Object to be locked
102         * @return true if successful, else false
103         *
104         */
105        public boolean upgradeLock(TransactionImpl tx, Object obj)
106        {
107            LockEntry writer = getWriter(obj);
108            if (writer == null)
109            {
110                // if lock could be acquired return true
111                if (setWriter(tx, obj))
112                    return true;
113                // else try again
114                else
115                    return upgradeLock(tx, obj);
116            }
117            if (writer.isOwnedBy(tx))
118            {
119                return true;    // If I already have Write, then I've upgraded.
120            }
121    
122            return false;
123        }
124    
125        /**
126         * release a lock on Object obj for Transaction tx.
127         * @param tx the transaction releasing the lock
128         * @param obj the Object to be unlocked
129         * @return true if successful, else false
130         *
131         */
132        public boolean releaseLock(TransactionImpl tx, Object obj)
133        {
134            LockEntry writer = getWriter(obj);
135    
136            if (writer != null && writer.isOwnedBy(tx))
137            {
138                removeWriter(writer);
139                return true;
140            }
141    
142            if (hasReadLock(tx, obj))
143            {
144                removeReader(tx, obj);
145                return true;
146            }
147            return false;
148        }
149    
150        /**
151         * checks whether the specified Object obj is read-locked by Transaction tx.
152         * @param tx the transaction
153         * @param obj the Object to be checked
154         * @return true if lock exists, else false
155         */
156        public boolean checkRead(TransactionImpl tx, Object obj)
157        {
158            if (hasReadLock(tx, obj))
159            {
160                return true;
161            }
162            LockEntry writer = getWriter(obj);
163            if (writer.isOwnedBy(tx))
164            {
165                return true;
166            }
167            return false;
168        }
169    
170        /**
171         * checks whether the specified Object obj is write-locked by Transaction tx.
172         * @param tx the transaction
173         * @param obj the Object to be checked
174         * @return true if lock exists, else false
175         */
176        public boolean checkWrite(TransactionImpl tx, Object obj)
177        {
178            LockEntry writer = getWriter(obj);
179            if (writer == null)
180                return false;
181            else if (writer.isOwnedBy(tx))
182                return true;
183            else
184                return false;
185        }
186    }