001 package org.apache.ojb.otm.lock.isolation;
002
003 /* Copyright 2003-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 java.util.Collection;
019 import java.util.Iterator;
020
021 import org.apache.ojb.otm.core.Transaction;
022 import org.apache.ojb.otm.lock.LockingException;
023 import org.apache.ojb.otm.lock.ObjectLock;
024
025 public class RepeatableReadIsolation extends AbstractIsolation
026 {
027
028 /**
029 * @see org.apache.ojb.otm.lock.isolation.TransactionIsolation#readLock(Transaction, ObjectLock)
030 */
031 public void readLock(Transaction tx, ObjectLock lock)
032 throws LockingException
033 {
034 Transaction writer = lock.getWriter();
035 if (writer == null)
036 {
037 lock.readLock(tx);
038 if (lock.getWriter() != null)
039 {
040 lock.releaseLock(tx);
041 readLock(tx, lock);
042 }
043 }
044 else if (tx != writer)
045 {
046 lock.waitForTx(writer);
047 readLock(tx, lock);
048 }
049 // else if tx is the writer, it can also read.
050 }
051
052 /**
053 * @see org.apache.ojb.otm.lock.isolation.TransactionIsolation#writeLock(Transaction, ObjectLock)
054 */
055 public void writeLock(Transaction tx, ObjectLock lock)
056 throws LockingException
057 {
058 Collection readers = lock.getReaders();
059
060 if (!readers.isEmpty())
061 {
062 for (Iterator it = readers.iterator(); it.hasNext(); )
063 {
064 Transaction reader = (Transaction) it.next();
065
066 if (reader != tx)
067 {
068 lock.waitForTx(reader);
069 writeLock(tx, lock);
070 return;
071 }
072 }
073 }
074
075 lock.writeLock(tx);
076 readers = lock.getReaders();
077 if (readers.size() > 1)
078 {
079 lock.releaseLock(tx);
080 writeLock(tx, lock);
081 }
082 }
083 }