Return-Path: Delivered-To: apmail-db-ojb-dev-archive@www.apache.org Received: (qmail 3707 invoked from network); 11 Nov 2004 23:39:05 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur-2.apache.org with SMTP; 11 Nov 2004 23:39:05 -0000 Received: (qmail 52114 invoked by uid 500); 11 Nov 2004 23:39:04 -0000 Delivered-To: apmail-db-ojb-dev-archive@db.apache.org Received: (qmail 52070 invoked by uid 500); 11 Nov 2004 23:39:04 -0000 Mailing-List: contact ojb-dev-help@db.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "OJB Developers List" Reply-To: "OJB Developers List" Delivered-To: mailing list ojb-dev@db.apache.org Received: (qmail 52036 invoked by uid 500); 11 Nov 2004 23:39:04 -0000 Received: (qmail 52031 invoked by uid 99); 11 Nov 2004 23:39:03 -0000 Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.28) with SMTP; Thu, 11 Nov 2004 15:39:03 -0800 Received: (qmail 3669 invoked by uid 1510); 11 Nov 2004 23:39:02 -0000 Date: 11 Nov 2004 23:39:02 -0000 Message-ID: <20041111233902.3668.qmail@minotaur.apache.org> From: arminw@apache.org To: db-ojb-cvs@apache.org Subject: cvs commit: db-ojb/src/java/org/apache/ojb/broker/locking LockEntry.java LockMap.java LockStrategyManager.java ReadUncommittedStrategy.java AbstractLockStrategy.java LockManagerDefaultImpl.java LockMapRemoteImpl.java ReadCommittedStrategy.java LockMapInMemoryImpl.java LockServerServlet.java LockStrategy.java LockManager.java SerializableStrategy.java RepeatableReadStrategy.java X-Virus-Checked: Checked X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N arminw 2004/11/11 15:39:02 Modified: src/java/org/apache/ojb/broker/locking LockEntry.java LockMap.java LockStrategyManager.java ReadUncommittedStrategy.java AbstractLockStrategy.java LockManagerDefaultImpl.java LockMapRemoteImpl.java ReadCommittedStrategy.java LockMapInMemoryImpl.java LockServerServlet.java LockStrategy.java LockManager.java SerializableStrategy.java RepeatableReadStrategy.java Log: merge with 1.0.x branch LockManager#releaseLock: if a write lock was found, now all read locks will be released too. http://nagoya.apache.org/eyebrowse/ReadMsg?listName=ojb-user@db.apache.org&msgNo=14885 LockMap#releaseLock method signature changed Revision Changes Path 1.3 +17 -20 db-ojb/src/java/org/apache/ojb/broker/locking/LockEntry.java Index: LockEntry.java =================================================================== RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/locking/LockEntry.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- LockEntry.java 20 Sep 2004 14:32:26 -0000 1.2 +++ LockEntry.java 11 Nov 2004 23:39:01 -0000 1.3 @@ -18,9 +18,7 @@ import java.io.Serializable; /** - * a persistent entry for locks. All locks that are hold from - * transaction on objects are represented by a LockENtry and made - * persistent to the database. + * A lock entry encapsulates locking information. * * @author Thomas Mahler */ @@ -38,9 +36,9 @@ public static int LOCK_WRITE = 1; /** - * the unique OID of the object to be locked. + * the object to be locked. */ - private Object lockedObj; + private Object resourceId; /** * key for locked object @@ -67,13 +65,13 @@ /** * Multiargument constructor for fast loading of LockEntries by OJB. */ - public LockEntry(Object lockedObj, + public LockEntry(Object resourceId, Object key, long timestamp, int isolationLevel, int lockType) { - this.lockedObj = lockedObj; + this.resourceId = resourceId; this.key = key; this.timestamp = timestamp; this.isolationLevel = isolationLevel; @@ -82,24 +80,24 @@ } /** - * build a LockEntry from an OID and a Transaction ID + * Build an entry only from resourceId and lock key. */ - public LockEntry(Object lockedObj, Object key) + public LockEntry(Object resourceId, Object key) { - this.lockedObj = lockedObj; + this.resourceId = resourceId; this.key = key; } /** - * returns the OID STring of the locked object. + * Returns the resource id of the locked object (or the locked object itself). */ - public Object getLockedObj() + public Object getResourceId() { - return lockedObj; + return resourceId; } /** - * returns the GUID string of the locking transaction. + * Returns lock key. */ public Object getKey() { @@ -144,7 +142,7 @@ } /** - * returns true if this lock is owned by transaction tx, else false. + * Returns true if this lock is owned by the specified key. */ public boolean isOwnedBy(Object key) { @@ -163,13 +161,13 @@ } /** - * Sets the lockedObj. + * Sets the resourceId. * - * @param lockedObj The lockedObj to set + * @param resourceId The resourceId to set */ - public void setLockedObj(String lockedObj) + public void setresourceId(String resourceId) { - this.lockedObj = lockedObj; + this.resourceId = resourceId; } /** @@ -191,5 +189,4 @@ { this.key = key; } - } 1.3 +37 -22 db-ojb/src/java/org/apache/ojb/broker/locking/LockMap.java Index: LockMap.java =================================================================== RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/locking/LockMap.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- LockMap.java 20 Sep 2004 14:32:26 -0000 1.2 +++ LockMap.java 11 Nov 2004 23:39:01 -0000 1.3 @@ -17,53 +17,68 @@ import java.util.Collection; +/** + * This class encapsulates the locked objects and is responsible to guarantee + * consistence of locked objects. + *

+ * The default implementation {@link LockMapInMemoryImpl} only provide support for + * single JVM locking. + *

+ * + * @see LockMapInMemoryImpl + * @version $Id$ + */ public interface LockMap { /** - * returns the LockEntry for the Writer of object obj. + * Returns the {@link LockEntry} for the writer + * for the specified resource object. * If now writer exists, null is returned. */ - public LockEntry getWriter(Object lockedObj); + public LockEntry getWriter(Object resourceId); /** - * returns a collection of Reader LockEntries for object obj. - * If now LockEntries could be found an empty Vector is returned. + * Returns a collection of Reader {@link LockEntry} instances + * for the specified resource object + * If no lock entry could be found an empty collection is returned. */ - public Collection getReaders(Object lockedObj); + public Collection getReaders(Object resourceId); /** - * Add a reader lock entry for transaction tx on object obj - * to the persistent storage. + * Add a reader lock entry for the specified key on + * the resource object. */ - public boolean addReader(Object key, Object lockedObj, int isolationLevel); + public boolean addReader(Object key, Object resourceId, int isolationLevel); /** - * remove a reader lock entry for transaction tx on object obj - * from the persistent storage. + * Remove a reader lock entry for the specified key on + * the resource object, returns true if an reader + * was found and removed. */ - public void removeReader(Object key, Object lockedObj); + public boolean removeReader(Object key, Object resourceId); /** - * remove a writer lock entry for transaction tx on object obj - * from the persistent storage. + * Remove a writer lock entry for the specified key on + * the resource object, returns true if an reader + * was found and removed. */ - public void removeWriter(LockEntry writer); + public boolean removeWriter(LockEntry writer); /** - * upgrade a reader lock entry for transaction tx on object obj - * and write it to the persistent storage. + * Upgrade a reader lock entry for the specified key on + * the resource object. */ public boolean upgradeLock(LockEntry reader); /** - * generate a writer lock entry for transaction tx on object obj - * and write it to the persistent storage. + * Generate a writer lock entry for the specified key on + * the resource object. */ - public boolean setWriter(Object key, Object lockedObj, int isolationLevel); + public boolean setWriter(Object key, Object resourceId, int isolationLevel); /** - * check if there is a reader lock entry for transaction tx on object obj - * in the persistent storage. + * Check if there is a reader lock entry for the specified key on + * the resource object. */ - public boolean hasReadLock(Object key, Object lockedObj); + public boolean hasReadLock(Object key, Object resourceId); } 1.3 +0 -0 db-ojb/src/java/org/apache/ojb/broker/locking/LockStrategyManager.java Index: LockStrategyManager.java =================================================================== RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/locking/LockStrategyManager.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 1.3 +15 -19 db-ojb/src/java/org/apache/ojb/broker/locking/ReadUncommittedStrategy.java Index: ReadUncommittedStrategy.java =================================================================== RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/locking/ReadUncommittedStrategy.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- ReadUncommittedStrategy.java 20 Sep 2004 14:32:26 -0000 1.2 +++ ReadUncommittedStrategy.java 11 Nov 2004 23:39:01 -0000 1.3 @@ -24,9 +24,6 @@ * but since it will probably try to get them, it will * always give it to them. *

- * Locks are obtained on modifications to the database and held until end of - * transaction (EOT). Reading from the database does not involve any locking. - *

* Allows: * Dirty Reads * Non-Repeatable Reads @@ -46,7 +43,7 @@ /** * @see LockStrategy#readLock(java.lang.Object, java.lang.Object) */ - public boolean readLock(Object key, Object lockedObj) + public boolean readLock(Object key, Object resourceId) { return true; } @@ -54,15 +51,15 @@ /** * @see LockStrategy#writeLock(java.lang.Object, java.lang.Object) */ - public boolean writeLock(Object key, Object lockedObj) + public boolean writeLock(Object key, Object resourceId) { - LockEntry writer = getWriter(lockedObj); + LockEntry writer = getWriter(resourceId); if(writer == null) { - if(setWriter(key, lockedObj, ISOLATION_LEVEL)) + if(setWriter(key, resourceId, ISOLATION_LEVEL)) return true; else - return writeLock(key, lockedObj); + return writeLock(key, resourceId); } if(writer.isOwnedBy(key)) { @@ -74,15 +71,15 @@ /** * @see LockStrategy#upgradeLock(java.lang.Object, java.lang.Object) */ - public boolean upgradeLock(Object key, Object lockedObj) + public boolean upgradeLock(Object key, Object resourceId) { - LockEntry writer = getWriter(lockedObj); + LockEntry writer = getWriter(resourceId); if(writer == null) { - if(setWriter(key, lockedObj, ISOLATION_LEVEL)) + if(setWriter(key, resourceId, ISOLATION_LEVEL)) return true; else - return upgradeLock(key, lockedObj); + return upgradeLock(key, resourceId); } if(writer.isOwnedBy(key)) { @@ -94,13 +91,12 @@ /** * @see LockStrategy#readLock(java.lang.Object, java.lang.Object) */ - public boolean releaseLock(Object key, Object lockedObj) + public boolean releaseLock(Object key, Object resourceId) { - LockEntry writer = getWriter(lockedObj); + LockEntry writer = getWriter(resourceId); if(writer != null && writer.isOwnedBy(key)) { removeWriter(writer); - return true; } // readlocks cannot (and need not) be released, thus: return true; @@ -109,17 +105,17 @@ /** * @see LockStrategy#checkRead(java.lang.Object, java.lang.Object) */ - public boolean checkRead(Object key, Object lockedObj) + public boolean checkRead(Object key, Object resourceId) { - return true; + return checkWrite(key, resourceId); } /** * @see LockStrategy#checkWrite(java.lang.Object, java.lang.Object) */ - public boolean checkWrite(Object key, Object lockedObj) + public boolean checkWrite(Object key, Object resourceId) { - LockEntry writer = getWriter(lockedObj); + LockEntry writer = getWriter(resourceId); return (writer != null && writer.isOwnedBy(key)); } } 1.3 +23 -27 db-ojb/src/java/org/apache/ojb/broker/locking/AbstractLockStrategy.java Index: AbstractLockStrategy.java =================================================================== RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/locking/AbstractLockStrategy.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- AbstractLockStrategy.java 20 Sep 2004 14:32:26 -0000 1.2 +++ AbstractLockStrategy.java 11 Nov 2004 23:39:01 -0000 1.3 @@ -18,7 +18,7 @@ import java.util.Collection; /** - * The base class of all LockingStrategies. It provides the basic + * The base class of all {@link LockStrategy}. It provides the basic * infrastructure to read and write locks to the persistent storage. * * @author Thomas Mahler @@ -41,54 +41,52 @@ } /** - * returns the LockEntry for the Writer of object obj. + * returns the LockEntry for the Writer of object resourceId. * If now writer exists, null is returned. */ - protected LockEntry getWriter(Object lockedObj) + protected LockEntry getWriter(Object resourceId) { - return lockMap.getWriter(lockedObj); + return lockMap.getWriter(resourceId); } /** - * returns a collection of Reader LockEntries for object obj. + * returns a collection of Reader LockEntries for object resourceId. * If now LockEntries could be found an empty Vector is returned. */ - protected Collection getReaders(Object lockedObj) + protected Collection getReaders(Object resourceId) { - return lockMap.getReaders(lockedObj); + return lockMap.getReaders(resourceId); } /** - * Add a reader lock entry for transaction tx on object obj + * Add a reader lock entry for object 'key' on object resourceId * to the persistent storage. */ - protected boolean addReader(Object key, Object lockedObj, int isolationLevel) + protected boolean addReader(Object key, Object resourceId, int isolationLevel) { - return lockMap.addReader(key, lockedObj, isolationLevel); + return lockMap.addReader(key, resourceId, isolationLevel); } /** - * remove a reader lock entry for transaction tx on object obj + * Remove a reader lock entry for lock key on object resourceId * from the persistent storage. */ - protected void removeReader(Object key, Object lockedObj) + protected boolean removeReader(Object key, Object resourceId) { - lockMap.removeReader(key, lockedObj); + return lockMap.removeReader(key, resourceId); } /** - * remove a writer lock entry for transaction tx on object obj - * from the persistent storage. + * Remove a writer lock entry for given {@link LockEntry}. */ - protected void removeWriter(LockEntry writer) + protected boolean removeWriter(LockEntry writer) { - lockMap.removeWriter(writer); + return lockMap.removeWriter(writer); } /** - * upgrade a reader lock entry for transaction tx on object obj - * and write it to the persistent storage. + * Upgrade a reader lock entry for given {@link LockEntry}. */ protected boolean upgradeLock(LockEntry reader) { @@ -96,20 +94,18 @@ } /** - * generate a writer lock entry for transaction tx on object obj - * and write it to the persistent storage. + * Generate a writer lock entry for the specified key on object resourceId. */ - protected boolean setWriter(Object key, Object lockedObj, int isolationLevel) + protected boolean setWriter(Object key, Object resourceId, int isolationLevel) { - return lockMap.setWriter(key, lockedObj, isolationLevel); + return lockMap.setWriter(key, resourceId, isolationLevel); } /** - * check if there is a reader lock entry for transaction tx on object obj - * in the persistent storage. + * check if there is a reader lock entry for given key on object resourceId. */ - protected boolean hasReadLock(Object key, Object lockedObj) + protected boolean hasReadLock(Object key, Object resourceId) { - return lockMap.hasReadLock(key, lockedObj); + return lockMap.hasReadLock(key, resourceId); } } 1.3 +36 -48 db-ojb/src/java/org/apache/ojb/broker/locking/LockManagerDefaultImpl.java Index: LockManagerDefaultImpl.java =================================================================== RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/locking/LockManagerDefaultImpl.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- LockManagerDefaultImpl.java 20 Sep 2004 14:32:26 -0000 1.2 +++ LockManagerDefaultImpl.java 11 Nov 2004 23:39:01 -0000 1.3 @@ -20,28 +20,23 @@ /** * The OJB default implementation of a Locking mechanism. + *

* This Implementation supports 4 transaction isolation levels - * as specified in the interface org.apache.ojb.broker.metadata.IsolationLevels: - * public final int IL_READ_UNCOMMITTED = 0; - * public final int IL_READ_COMMITTED = 1; - * public final int IL_REPEATABLE_READ = 2; - * public final int IL_SERIALIZABLE = 3; + * as specified in the interface {@link org.apache.ojb.broker.metadata.IsolationLevels}: + *
public final int IL_READ_UNCOMMITTED = 0; + *
public final int IL_READ_COMMITTED = 1; + *
public final int IL_REPEATABLE_READ = 2; + *
public final int IL_SERIALIZABLE = 3; + *

* Isolationlevels can be adjusted per class. - * The proper lockhandling is done in the respective LockStrategy implementation. - * This default implementation provides persistent Locks that are stored in - * a special database table. - * To keep the locks in the database and not in memory allows to use - * them accross multiple distributed ODMG clients. + * The proper lock handling is done in the respective + * {@link LockStrategy} implementation. *

- * Of course this solution causes a lot of database reads and writes even if - * no real application data is written to the database. This solution may - * thus not be suited for all environments. As the LockManager is pluggable - * its possible to replace the default implementation by user defined - * implementations. - * A different solution might be to implement the LockManager as an additional - * standalone server, that allows to elminate additional db reads and writes. + * As the LockManager is pluggable its possible to replace the default implementation + * by user defined implementations. * * @author thma + * @version $Id$ */ public class LockManagerDefaultImpl implements LockManager { @@ -54,69 +49,62 @@ } /** - * aquires a readlock for transaction tx on object obj. - * Returns true if successful, else false. + * @see LockManager#readLock(Object, Object, int) */ - public synchronized boolean readLock(Object key, Object lockedObj, int isolationLevel) + public synchronized boolean readLock(Object key, Object resourceId, int isolationLevel) { - if(log.isDebugEnabled()) log.debug("LM.readLock(tx-" + key + ", " + lockedObj + ")"); + if(log.isDebugEnabled()) log.debug("LM.readLock(tx-" + key + ", " + resourceId + ")"); LockStrategy lockStrategy = lockStrategyManager.getStrategyFor(isolationLevel); - return lockStrategy.readLock(key, lockedObj); + return lockStrategy.readLock(key, resourceId); } /** - * aquires a writelock for transaction tx on object obj. - * Returns true if successful, else false. + * @see LockManager#writeLock(Object, Object, int) */ - public synchronized boolean writeLock(Object key, Object lockedObj, int isolationLevel) + public synchronized boolean writeLock(Object key, Object resourceId, int isolationLevel) { - if(log.isDebugEnabled()) log.debug("LM.writeLock(tx-" + key + ", " + lockedObj + ")"); + if(log.isDebugEnabled()) log.debug("LM.writeLock(tx-" + key + ", " + resourceId + ")"); LockStrategy lockStrategy = lockStrategyManager.getStrategyFor(isolationLevel); - return lockStrategy.writeLock(key, lockedObj); + return lockStrategy.writeLock(key, resourceId); } /** - * upgrades readlock for transaction tx on object obj to a writelock. - * If no readlock existed a writelock is acquired anyway. - * Returns true if successful, else false. + * @see LockManager#upgradeLock(Object, Object, int) */ - public synchronized boolean upgradeLock(Object key, Object lockedObj, int isolationLevel) + public synchronized boolean upgradeLock(Object key, Object resourceId, int isolationLevel) { - if(log.isDebugEnabled()) log.debug("LM.upgradeLock(tx-" + key + ", " + lockedObj + ")"); + if(log.isDebugEnabled()) log.debug("LM.upgradeLock(tx-" + key + ", " + resourceId + ")"); LockStrategy lockStrategy = lockStrategyManager.getStrategyFor(isolationLevel); - return lockStrategy.upgradeLock(key, lockedObj); + return lockStrategy.upgradeLock(key, resourceId); } /** - * releases a lock for transaction tx on object obj. - * Returns true if successful, else false. + * @see LockManager#releaseLock(Object, Object, int) */ - public synchronized boolean releaseLock(Object key, Object lockedObj, int isolationLevel) + public synchronized boolean releaseLock(Object key, Object resourceId, int isolationLevel) { - if(log.isDebugEnabled()) log.debug("LM.releaseLock(tx-" + key + ", " + lockedObj + ")"); + if(log.isDebugEnabled()) log.debug("LM.releaseLock(tx-" + key + ", " + resourceId + ")"); LockStrategy lockStrategy = lockStrategyManager.getStrategyFor(isolationLevel); - return lockStrategy.releaseLock(key, lockedObj); + return lockStrategy.releaseLock(key, resourceId); } /** - * checks if there is a readlock for transaction tx on object obj. - * Returns true if so, else false. + * @see LockManager#checkRead(Object, Object, int) */ - public synchronized boolean checkRead(Object key, Object lockedObj, int isolationLevel) + public synchronized boolean checkRead(Object key, Object resourceId, int isolationLevel) { - if(log.isDebugEnabled()) log.debug("LM.checkRead(tx-" + key + ", " + lockedObj + ")"); + if(log.isDebugEnabled()) log.debug("LM.checkRead(tx-" + key + ", " + resourceId + ')'); LockStrategy lockStrategy = lockStrategyManager.getStrategyFor(isolationLevel); - return lockStrategy.checkRead(key, lockedObj); + return lockStrategy.checkRead(key, resourceId); } /** - * checks if there is a writelock for transaction tx on object obj. - * Returns true if so, else false. + * @see LockManager#checkWrite(Object, Object, int) */ - public synchronized boolean checkWrite(Object key, Object lockedObj, int isolationLevel) + public synchronized boolean checkWrite(Object key, Object resourceId, int isolationLevel) { - if(log.isDebugEnabled()) log.debug("LM.checkWrite(tx-" + key + ", " + lockedObj + ")"); + if(log.isDebugEnabled()) log.debug("LM.checkWrite(tx-" + key + ", " + resourceId + ")"); LockStrategy lockStrategy = lockStrategyManager.getStrategyFor(isolationLevel); - return lockStrategy.checkWrite(key, lockedObj); + return lockStrategy.checkWrite(key, resourceId); } } 1.3 +48 -52 db-ojb/src/java/org/apache/ojb/broker/locking/LockMapRemoteImpl.java Index: LockMapRemoteImpl.java =================================================================== RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/locking/LockMapRemoteImpl.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- LockMapRemoteImpl.java 20 Sep 2004 14:32:26 -0000 1.2 +++ LockMapRemoteImpl.java 11 Nov 2004 23:39:01 -0000 1.3 @@ -47,15 +47,14 @@ private static URL lockservlet = null; /** - * returns the LockEntry for the Writer of object obj. - * If now writer exists, null is returned. + * @see LockMap#getWriter(Object) */ - public LockEntry getWriter(Object lockedObj) + public LockEntry getWriter(Object resourceId) { LockEntry result = null; try { - result = getWriterRemote(lockedObj); + result = getWriterRemote(resourceId); } catch(Throwable e) { @@ -64,7 +63,7 @@ return result; } - private LockEntry getWriterRemote(Object lockedObj) + private LockEntry getWriterRemote(Object resourceId) throws MalformedURLException, IOException, @@ -72,7 +71,7 @@ ClassNotFoundException { byte selector = (byte) 'w'; - byte[] requestBarr = buildRequestArray(lockedObj, selector); + byte[] requestBarr = buildRequestArray(resourceId, selector); HttpURLConnection conn = getHttpUrlConnection(); @@ -125,16 +124,15 @@ /** - * returns a collection of Reader LockEntries for object obj. - * If now LockEntries could be found an empty Vector is returned. + * @see LockMap#getReaders(Object) */ - public Collection getReaders(Object lockedObj) + public Collection getReaders(Object resourceId) { Collection result = null; try { byte selector = (byte) 'r'; - byte[] requestBarr = buildRequestArray(lockedObj, selector); + byte[] requestBarr = buildRequestArray(resourceId, selector); HttpURLConnection conn = getHttpUrlConnection(); @@ -162,14 +160,13 @@ /** - * Add a reader lock entry for transaction tx on object obj - * to the persistent storage. + * @see LockMap#addReader(Object, Object, int) */ - public boolean addReader(Object key, Object lockedObj, int isolationLevel) + public boolean addReader(Object key, Object resourceId, int isolationLevel) { try { - LockEntry lock = new LockEntry(lockedObj, + LockEntry lock = new LockEntry(resourceId, key, System.currentTimeMillis(), isolationLevel, @@ -179,7 +176,7 @@ } catch(Throwable t) { - log.error("Cannot store LockEntry for '" + lockedObj + "' using key '" + key + "'", t); + log.error("Cannot store LockEntry for '" + resourceId + "' using key '" + key + "'", t); return false; } } @@ -223,23 +220,24 @@ } /** - * remove a reader lock entry for transaction tx on object obj - * from the persistent storage. + * @see LockMap#removeReader(Object, Object) */ - public void removeReader(Object key, Object lockedObj) + public boolean removeReader(Object key, Object resourceId) { + boolean result = false; try { - LockEntry lock = new LockEntry(lockedObj, key); - removeReaderRemote(lock); + LockEntry lock = new LockEntry(resourceId, key); + result = removeReaderRemote(lock); } catch(Throwable t) { - log.error("Cannot remove LockEntry for '" + lockedObj + "' using key '" + key + "'"); + log.error("Cannot remove LockEntry for resource '" + resourceId + "' using key '" + key + "'"); } + return result; } - private void removeReaderRemote(LockEntry lock) throws IOException, ClassNotFoundException + private boolean removeReaderRemote(LockEntry lock) throws IOException, ClassNotFoundException { byte selector = (byte) 'e'; byte[] requestBarr = buildRequestArray(lock, selector); @@ -260,30 +258,32 @@ ois.close(); out.close(); conn.disconnect(); - if(!result.booleanValue()) - { - throw new PersistenceBrokerException("could not remove reader!"); - } - +// TODO: arminw: why should we throw an exception? +// if(!result.booleanValue()) +// { +// throw new PersistenceBrokerException("could not remove reader!"); +// } + return result.booleanValue(); } /** - * remove a writer lock entry for transaction tx on object obj - * from the persistent storage. + * @see LockMap#removeWriter(LockEntry) */ - public void removeWriter(LockEntry writer) + public boolean removeWriter(LockEntry writer) { + boolean result = false; try { - removeWriterRemote(writer); + result = removeWriterRemote(writer); } catch(Throwable t) { log.error("Cannot remove LockEntry", t); } + return result; } - private void removeWriterRemote(LockEntry lock) throws IOException, ClassNotFoundException + private boolean removeWriterRemote(LockEntry lock) throws IOException, ClassNotFoundException { byte selector = (byte) 'm'; byte[] requestBarr = buildRequestArray(lock, selector); @@ -304,16 +304,16 @@ ois.close(); out.close(); conn.disconnect(); - if(!result.booleanValue()) - { - throw new PersistenceBrokerException("could not remove writer!"); - } - +// TODO: arminw: why should we throw an exception? +// if(!result.booleanValue()) +// { +// throw new PersistenceBrokerException("could not remove writer!"); +// } + return result.booleanValue(); } /** - * upgrade a reader lock entry for transaction tx on object obj - * and write it to the persistent storage. + * @see LockMap#upgradeLock(LockEntry) */ public boolean upgradeLock(LockEntry reader) { @@ -359,14 +359,13 @@ } /** - * generate a writer lock entry for transaction tx on object obj - * and write it to the persistent storage. + * @see LockMap#setWriter(Object, Object, int) */ - public boolean setWriter(Object key, Object lockedObj, int isolationLevel) + public boolean setWriter(Object key, Object resourceId, int isolationLevel) { try { - LockEntry lock = new LockEntry(lockedObj, + LockEntry lock = new LockEntry(resourceId, key, System.currentTimeMillis(), isolationLevel, @@ -377,7 +376,7 @@ } catch(Throwable t) { - log.error("Cannot set LockEntry for '" + lockedObj + "' using key '" + key + "'"); + log.error("Cannot set LockEntry for '" + resourceId + "' using key '" + key + "'"); return false; } } @@ -411,20 +410,19 @@ } /** - * check if there is a reader lock entry for transaction tx on object obj - * in the persistent storage. + * @see LockMap#hasReadLock(Object, Object) */ - public boolean hasReadLock(Object key, Object lockedObj) + public boolean hasReadLock(Object key, Object resourceId) { try { - LockEntry lock = new LockEntry(lockedObj, key); + LockEntry lock = new LockEntry(resourceId, key); boolean result = hasReadLockRemote(lock); return result; } catch(Throwable t) { - log.error("Cannot check read lock for '" + lockedObj + "' using key '" + key + "'", t); + log.error("Cannot check read lock for '" + resourceId + "' using key '" + key + "'", t); return false; } } @@ -453,7 +451,6 @@ return result.booleanValue(); } - /** * @see org.apache.ojb.broker.util.configuration.Configurable#configure(org.apache.ojb.broker.util.configuration.Configuration) */ @@ -470,5 +467,4 @@ } } - } 1.3 +40 -35 db-ojb/src/java/org/apache/ojb/broker/locking/ReadCommittedStrategy.java Index: ReadCommittedStrategy.java =================================================================== RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/locking/ReadCommittedStrategy.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- ReadCommittedStrategy.java 20 Sep 2004 14:32:26 -0000 1.2 +++ ReadCommittedStrategy.java 11 Nov 2004 23:39:01 -0000 1.3 @@ -18,7 +18,7 @@ import org.apache.ojb.broker.metadata.IsolationLevels; /** - * The implementation of the Commited Reads Locking stra + * The implementation of the Commited Reads Locking strategy. * ReadCommitted - Reads and Writes require locks. *

* Locks are acquired for reading and modifying the database. @@ -26,8 +26,8 @@ * are held until EOT. *

* Allows: - * Non-Repeatable Reads - * Phantom Readstegy. + * Non-Repeatable Reads, + * Phantom Reads. * * @author Thomas Mahler & David Dixon-Peugh */ @@ -43,20 +43,20 @@ /** * @see LockStrategy#readLock(java.lang.Object, java.lang.Object) */ - public boolean readLock(Object key, Object lockedObj) + public boolean readLock(Object key, Object resourceId) { - LockEntry writer = getWriter(lockedObj); + LockEntry writer = getWriter(resourceId); if(writer == null) { - addReader(key, lockedObj, ISOLATION_LEVEL); + addReader(key, resourceId, ISOLATION_LEVEL); // if there has been a successful write locking, try again - if(getWriter(lockedObj) == null) + if(getWriter(resourceId) == null) return true; else { - removeReader(key, lockedObj); - return readLock(key, lockedObj); + removeReader(key, resourceId); + return readLock(key, resourceId); } } if(writer.isOwnedBy(key)) @@ -72,18 +72,18 @@ /** * @see LockStrategy#writeLock(java.lang.Object, java.lang.Object) */ - public boolean writeLock(Object key, Object lockedObj) + public boolean writeLock(Object key, Object resourceId) { - LockEntry writer = getWriter(lockedObj); + LockEntry writer = getWriter(resourceId); // if there is no writer yet we can try to get the global write lock if(writer == null) { // if lock could be acquired return true - if(setWriter(key, lockedObj, ISOLATION_LEVEL)) + if(setWriter(key, resourceId, ISOLATION_LEVEL)) return true; // else try again else - return writeLock(key, lockedObj); + return writeLock(key, resourceId); } if(writer.isOwnedBy(key)) { @@ -96,17 +96,17 @@ /** * @see LockStrategy#upgradeLock(java.lang.Object, java.lang.Object) */ - public boolean upgradeLock(Object key, Object lockedObj) + public boolean upgradeLock(Object key, Object resourceId) { - LockEntry writer = getWriter(lockedObj); + LockEntry writer = getWriter(resourceId); if(writer == null) { // if lock could be acquired return true - if(setWriter(key, lockedObj, ISOLATION_LEVEL)) + if(setWriter(key, resourceId, ISOLATION_LEVEL)) return true; // else try again else - return upgradeLock(key, lockedObj); + return upgradeLock(key, resourceId); } if(writer.isOwnedBy(key)) { @@ -119,35 +119,40 @@ /** * @see LockStrategy#readLock(java.lang.Object, java.lang.Object) */ - public boolean releaseLock(Object key, Object lockedObj) + public boolean releaseLock(Object key, Object resourceId) { - LockEntry writer = getWriter(lockedObj); - + LockEntry writer = getWriter(resourceId); + boolean result = false; +// if(writer != null && writer.isOwnedBy(key)) +// { +// removeWriter(writer); +// result = true; +// } +// +// if(hasReadLock(key, resourceId)) +// { +// result = removeReader(key, resourceId); +// result = true; +// } if(writer != null && writer.isOwnedBy(key)) { - removeWriter(writer); - return true; + result = removeWriter(writer); } - - if(hasReadLock(key, lockedObj)) - { - removeReader(key, lockedObj); - return true; - } - return false; + if(removeReader(key, resourceId)) result = true; + return result; } /** * @see LockStrategy#checkRead(java.lang.Object, java.lang.Object) */ - public boolean checkRead(Object key, Object lockedObj) + public boolean checkRead(Object key, Object resourceId) { - if(hasReadLock(key, lockedObj)) + if(hasReadLock(key, resourceId)) { return true; } - LockEntry writer = getWriter(lockedObj); - if(writer.isOwnedBy(key)) + LockEntry writer = getWriter(resourceId); + if(writer != null && writer.isOwnedBy(key)) { return true; } @@ -157,9 +162,9 @@ /** * @see LockStrategy#checkWrite(java.lang.Object, java.lang.Object) */ - public boolean checkWrite(Object key, Object lockedObj) + public boolean checkWrite(Object key, Object resourceId) { - LockEntry writer = getWriter(lockedObj); + LockEntry writer = getWriter(resourceId); if(writer == null) return false; else if(writer.isOwnedBy(key)) 1.3 +62 -73 db-ojb/src/java/org/apache/ojb/broker/locking/LockMapInMemoryImpl.java Index: LockMapInMemoryImpl.java =================================================================== RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/locking/LockMapInMemoryImpl.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- LockMapInMemoryImpl.java 20 Sep 2004 14:32:26 -0000 1.2 +++ LockMapInMemoryImpl.java 11 Nov 2004 23:39:01 -0000 1.3 @@ -18,14 +18,13 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.Hashtable; import java.util.Iterator; import java.util.Map; -import java.util.Hashtable; /** - * We use a HashMap and synchronize blocks of access for a get "check" then put - * operation. We cannot use the hashtable as you could check in one synchronized call - * then put in another while a different thread is doing the same thing. + * This implementation of {@link LockMap} supports locking for single JVM + * applications. * * @author Matthew Baird * update for use of Hashmap with synchronization. @@ -48,42 +47,39 @@ private static int MAX_LOCKS_TO_CLEAN = 50; /** - * returns the LockEntry for the Writer of object obj. - * If now writer exists, null is returned. + * @see LockMap#getWriter(Object) */ - public LockEntry getWriter(Object lockedObj) + public LockEntry getWriter(Object resourceId) { checkTimedOutLocks(); ObjectLocks objectLocks = null; synchronized(locktable) { - objectLocks = (ObjectLocks) locktable.get(lockedObj); + objectLocks = (ObjectLocks) locktable.get(resourceId); } return objectLocks == null ? null : objectLocks.getWriter(); } /** - * returns a collection of Reader LockEntries for object obj. - * If no LockEntries could be found an empty Vector is returned. + * @see LockMap#getReaders(Object) */ - public Collection getReaders(Object lockedObj) + public Collection getReaders(Object resourceId) { ObjectLocks objectLocks = null; synchronized(locktable) { - objectLocks = (ObjectLocks) locktable.get(lockedObj); + objectLocks = (ObjectLocks) locktable.get(resourceId); } return objectLocks == null ? new ArrayList() : objectLocks.getReaders().values(); } /** - * Add a reader lock entry for transaction tx on object obj - * to the persistent storage. + * @see LockMap#addReader(Object, Object, int) */ - public boolean addReader(Object key, Object lockedObj, int isolationLevel) + public boolean addReader(Object key, Object resourceId, int isolationLevel) { checkTimedOutLocks(); - LockEntry reader = new LockEntry(lockedObj, + LockEntry reader = new LockEntry(resourceId, key, System.currentTimeMillis(), isolationLevel, @@ -102,7 +98,7 @@ */ synchronized(locktable) { - Object oid = reader.getLockedObj(); + Object oid = reader.getResourceId(); objectLocks = (ObjectLocks) locktable.get(oid); if(objectLocks == null) { @@ -114,27 +110,23 @@ } /** - * remove a reader lock entry for transaction tx on object obj - * from the persistent storage. + * @see LockMap#removeReader(Object, Object) */ - public void removeReader(Object key, Object lockedObj) + public boolean removeReader(Object key, Object resourceId) { checkTimedOutLocks(); - removeReaderInternal(lockedObj, key); + return removeReaderInternal(resourceId, key); } - private void removeReaderInternal(Object lockedObj, Object key) + private boolean removeReaderInternal(Object resourceId, Object key) { + boolean result = false; ObjectLocks objectLocks = null; synchronized(locktable) { - objectLocks = (ObjectLocks) locktable.get(lockedObj); + objectLocks = (ObjectLocks) locktable.get(resourceId); } - if(objectLocks == null) - { - return; - } - else + if(objectLocks != null) { /** * MBAIRD, last one out, close the door and turn off the lights. @@ -144,41 +136,38 @@ synchronized(locktable) { Map readers = objectLocks.getReaders(); - readers.remove(key); + result = readers.remove(key) != null; if((objectLocks.getWriter() == null) && (readers.size() == 0)) { - locktable.remove(lockedObj); + locktable.remove(resourceId); } } } + return result; } void removeReaderByLock(LockEntry lock) { - Object lockedObj = lock.getLockedObj(); + Object resourceId = lock.getResourceId(); Object key = lock.getKey(); - removeReaderInternal(lockedObj, key); + removeReaderInternal(resourceId, key); } /** - * remove a writer lock entry for transaction tx on object obj - * from the persistent storage. + * @see LockMap#removeWriter(LockEntry) */ - public void removeWriter(LockEntry writer) + public boolean removeWriter(LockEntry writer) { checkTimedOutLocks(); + boolean result = false; - Object oid = writer.getLockedObj(); + Object oid = writer.getResourceId(); ObjectLocks objectLocks = null; synchronized(locktable) { objectLocks = (ObjectLocks) locktable.get(oid); } - if(objectLocks == null) - { - return; - } - else + if(objectLocks != null) { /** * MBAIRD, last one out, close the door and turn off the lights. @@ -187,26 +176,29 @@ */ synchronized(locktable) { - Map readers = objectLocks.getReaders(); - objectLocks.setWriter(null); + if(objectLocks.getWriter() != null) + { + objectLocks.setWriter(null); + result = true; + } // no need to check if writer is null, we just set it. - if(readers.size() == 0) + if(objectLocks.getReaders().size() == 0) { locktable.remove(oid); } } } + return result; } /** - * upgrade a reader lock entry for transaction tx on object obj - * and write it to the persistent storage. + * @see LockMap#upgradeLock(LockEntry) */ public boolean upgradeLock(LockEntry reader) { checkTimedOutLocks(); - Object oid = reader.getLockedObj(); + Object oid = reader.getResourceId(); ObjectLocks objectLocks = null; synchronized(locktable) { @@ -220,7 +212,7 @@ else { // add writer entry - LockEntry writer = new LockEntry(reader.getLockedObj(), + LockEntry writer = new LockEntry(reader.getResourceId(), reader.getKey(), System.currentTimeMillis(), reader.getIsolationLevel(), @@ -233,22 +225,21 @@ } /** - * generate a writer lock entry for transaction tx on object obj - * and write it to the persistent storage. + * @see LockMap#setWriter(Object, Object, int) */ - public boolean setWriter(Object key, Object lockedObj, int isolationLevel) + public boolean setWriter(Object key, Object resourceId, int isolationLevel) { checkTimedOutLocks(); - LockEntry writer = new LockEntry(lockedObj, + LockEntry writer = new LockEntry(resourceId, key, System.currentTimeMillis(), isolationLevel, LockEntry.LOCK_WRITE); - setWriterInternal(writer, lockedObj); + setWriterInternal(writer, resourceId); return true; } - private void setWriterInternal(LockEntry writer, Object lockedObj) + private void setWriterInternal(LockEntry writer, Object resourceId) { ObjectLocks objectLocks = null; /** @@ -257,11 +248,11 @@ */ synchronized(locktable) { - objectLocks = (ObjectLocks) locktable.get(lockedObj); + objectLocks = (ObjectLocks) locktable.get(resourceId); if(objectLocks == null) { objectLocks = new ObjectLocks(); - locktable.put(lockedObj, objectLocks); + locktable.put(resourceId, objectLocks); } } objectLocks.setWriter(writer); @@ -269,26 +260,25 @@ void setWriterByLock(LockEntry writer) { - Object oid = writer.getLockedObj(); + Object oid = writer.getResourceId(); setWriterInternal(writer, oid); } /** - * check if there is a reader lock entry for transaction tx on object obj - * in the persistent storage. + * @see LockMap#hasReadLock(Object, Object) */ - public boolean hasReadLock(Object key, Object lockedObj) + public boolean hasReadLock(Object key, Object resourceId) { checkTimedOutLocks(); - return hasReadLockInternal(lockedObj, key); + return hasReadLockInternal(resourceId, key); } - private boolean hasReadLockInternal(Object lockedObj, Object key) + private boolean hasReadLockInternal(Object resourceId, Object key) { ObjectLocks objectLocks = null; synchronized(locktable) { - objectLocks = (ObjectLocks) locktable.get(lockedObj); + objectLocks = (ObjectLocks) locktable.get(resourceId); } if(objectLocks == null) @@ -312,7 +302,7 @@ boolean hasReadLock(LockEntry entry) { - Object oid = entry.getLockedObj(); + Object oid = entry.getResourceId(); Object key = entry.getKey(); return hasReadLockInternal(oid, key); } @@ -396,7 +386,7 @@ //=============================================================== // inner class //=============================================================== - final class ObjectLocks + static final class ObjectLocks { private LockEntry writer; private Hashtable readers; @@ -408,22 +398,22 @@ readers = new Hashtable(); } - public LockEntry getWriter() + LockEntry getWriter() { return writer; } - public void setWriter(LockEntry writer) + void setWriter(LockEntry writer) { this.writer = writer; } - public Hashtable getReaders() + Hashtable getReaders() { return readers; } - public void addReader(LockEntry reader) + void addReader(LockEntry reader) { /** * MBAIRD: @@ -437,15 +427,14 @@ this.readers.put(reader.getKey(), reader); } - public long getYoungestReader() + long getYoungestReader() { return m_youngestReader; } - public LockEntry getReader(Object key) + LockEntry getReader(Object key) { return (LockEntry) this.readers.get(key); } } - } 1.3 +8 -8 db-ojb/src/java/org/apache/ojb/broker/locking/LockServerServlet.java Index: LockServerServlet.java =================================================================== RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/locking/LockServerServlet.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- LockServerServlet.java 20 Sep 2004 14:32:26 -0000 1.2 +++ LockServerServlet.java 11 Nov 2004 23:39:01 -0000 1.3 @@ -207,16 +207,16 @@ private LockEntry getWriter(byte[] data) throws IOException, ClassNotFoundException { LockEntry entry; - String lockedObj = (String) deserialize(data); - entry = lockmap.getWriter(lockedObj); + String resourceId = (String) deserialize(data); + entry = lockmap.getWriter(resourceId); return entry; } private Collection getAllReaders(byte[] data) throws IOException, ClassNotFoundException { Collection readers; - String lockedObj = (String) deserialize(data); - readers = lockmap.getReaders(lockedObj); + String resourceId = (String) deserialize(data); + readers = lockmap.getReaders(resourceId); return new ArrayList(readers); } @@ -298,17 +298,17 @@ private Boolean hasReadLock(byte[] data) throws IOException, ClassNotFoundException { - Boolean result = Boolean.TRUE; + boolean result = false; LockEntry lock = (LockEntry) deserialize(data); try { - lockmap.hasReadLock(lock); + result = lockmap.hasReadLock(lock); } catch(Throwable t) { - result = Boolean.FALSE; + result = false; } - return result; + return result ? Boolean.TRUE : Boolean.FALSE; } 1.3 +31 -29 db-ojb/src/java/org/apache/ojb/broker/locking/LockStrategy.java Index: LockStrategy.java =================================================================== RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/locking/LockStrategy.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- LockStrategy.java 20 Sep 2004 14:32:26 -0000 1.2 +++ LockStrategy.java 11 Nov 2004 23:39:01 -0000 1.3 @@ -16,65 +16,67 @@ */ - /** - * this interface defines method that a Locking Strategy must implement - * according to the transaction isolation level it represents. * + * This interface defines method that a Locking Strategy must implement + * according to the isolation level it represents. */ public interface LockStrategy { - /** - * acquire a read lock on Object obj for Transaction tx. + * Acquire a read lock on Object obj for Object key. * - * @param tx the transaction requesting the lock - * @param obj the Object to be locked + * @param key The key requesting the lock + * @param resourceId the resource object to be locked * @return true if successful, else false */ - public boolean readLock(Object key, Object lockedObj); + public boolean readLock(Object key, Object resourceId); /** - * acquire a write lock on Object obj for Transaction tx. + * Acquire a write lock on Object resourceId for Object key. * - * @param tx the transaction requesting the lock - * @param obj the Object to be locked + * @param key The key requesting the lock + * @param resourceId the resource object to be locked * @return true if successful, else false */ - public boolean writeLock(Object key, Object lockedObj); + public boolean writeLock(Object key, Object resourceId); /** - * acquire a lock upgrade (from read to write) lock on Object obj for Transaction tx. + * Acquire a lock upgrade (from read to write) lock on + * Object resourceId for Object key. * - * @param tx the transaction requesting the lock - * @param obj the Object to be locked + * @param key The key requesting the lock + * @param resourceId the resource object to be locked * @return true if successful, else false */ - public boolean upgradeLock(Object key, Object lockedObj); + public boolean upgradeLock(Object key, Object resourceId); /** - * release a lock on Object obj for Transaction tx. + * Release all locks on Object resourceId for Object key. * - * @param tx the transaction releasing the lock - * @param obj the Object to be unlocked - * @return true if successful, else false + * @param key The key requesting the lock + * @param resourceId the Object to be unlocked + * @return true if successful a read or write + * lock was released, else false */ - public boolean releaseLock(Object key, Object lockedObj); + public boolean releaseLock(Object key, Object resourceId); /** - * checks whether the specified Object obj is read-locked by Transaction tx. + * Checks whether the specified Object resourceId is + * read-locked by Object key. * - * @param tx the transaction - * @param obj the Object to be checked + * @param key The key requesting the lock + * @param resourceId the resource object to be checked * @return true if lock exists, else false */ - public boolean checkRead(Object key, Object lockedObj); + public boolean checkRead(Object key, Object resourceId); /** - * checks whether the specified Object obj is write-locked by Transaction tx. + * Checks whether the specified Object resourceId is + * write-locked by Object key. * - * @param tx the transaction - * @param obj the Object to be checked + * @param key The key requesting the lock + * @param resourceId the resource object to be checked * @return true if lock exists, else false */ - public boolean checkWrite(Object key, Object lockedObj); + public boolean checkWrite(Object key, Object resourceId); } 1.3 +30 -18 db-ojb/src/java/org/apache/ojb/broker/locking/LockManager.java Index: LockManager.java =================================================================== RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/locking/LockManager.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- LockManager.java 20 Sep 2004 14:32:26 -0000 1.2 +++ LockManager.java 11 Nov 2004 23:39:01 -0000 1.3 @@ -18,51 +18,63 @@ /** - * This interface declares the functionality of the OJB internal Locking mechanism. - * A default implementaion LockManagerDefaultImpl is provided. This implementaion - * keeps distributed locks in the database. The locking mechanisms thus involves a - * lot of database lookups and writes. For some environments this solution may not - * be adequate. OJB allows to provide user defined implementations of this interface. - * To activate a user defined LockManagerDefaultImpl it must be configured in the OJB.properties file. + * This interface declares the functionality of the OJB internal + * pessimistic Locking mechanism. + *

+ * A default implementaion {@link LockManagerDefaultImpl} is provided. + * OJB allows to provide user defined implementations of this interface. + * To activate a user defined LockManager implementation it must be configured in + * the OJB.properties file. Normally the default implementation of this class fit + * all requirements. + *

+ *

+ * Much more important are the pluggable {@link LockMap} implementations, these implementations + * keep the lock keys and the locked objects. + *

+ * + * @see LockManagerDefaultImpl + * @see LockStrategy + * @see LockMap * * @author thma + * @version $Id$ */ public interface LockManager { /** - * aquires a readlock for transaction tx on object obj. + * Aquires a readlock for lock key on resource object. * Returns true if successful, else false. */ - public abstract boolean readLock(Object key, Object lockedObj, int isolationLevel); + public abstract boolean readLock(Object key, Object resourceId, int isolationLevel); /** - * aquires a writelock for transaction tx on object obj. + * Aquires a writelock for lock key on resource object. * Returns true if successful, else false. */ - public abstract boolean writeLock(Object key, Object lockedObj, int isolationLevel); + public abstract boolean writeLock(Object key, Object resourceId, int isolationLevel); /** - * upgrades readlock for transaction tx on object obj to a writelock. + * Upgrades readlock for lock key on resource object. * If no readlock existed a writelock is acquired anyway. * Returns true if successful, else false. */ - public abstract boolean upgradeLock(Object key, Object lockedObj, int isolationLevel); + public abstract boolean upgradeLock(Object key, Object resourceId, int isolationLevel); /** - * releases a lock for transaction tx on object obj. + * Releases a lock for lock key on resource object. * Returns true if successful, else false. */ - public abstract boolean releaseLock(Object key, Object lockedObj, int isolationLevel); + public abstract boolean releaseLock(Object key, Object resourceId, int isolationLevel); /** - * checks if there is a readlock for transaction tx on object obj. + * Checks if there is a readlock for lock key on resource object. * Returns true if so, else false. */ - public abstract boolean checkRead(Object key, Object lockedObj, int isolationLevel); + public abstract boolean checkRead(Object key, Object resourceId, int isolationLevel); /** - * checks if there is a writelock for transaction tx on object obj. + * Checks if there is a writelock for lock key on resource object. * Returns true if so, else false. */ - public abstract boolean checkWrite(Object key, Object lockedObj, int isolationLevel); + public abstract boolean checkWrite(Object key, Object resourceId, int isolationLevel); } 1.3 +42 -38 db-ojb/src/java/org/apache/ojb/broker/locking/SerializableStrategy.java Index: SerializableStrategy.java =================================================================== RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/locking/SerializableStrategy.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- SerializableStrategy.java 20 Sep 2004 14:32:26 -0000 1.2 +++ SerializableStrategy.java 11 Nov 2004 23:39:01 -0000 1.3 @@ -37,30 +37,30 @@ /** * @see LockStrategy#readLock(java.lang.Object, java.lang.Object) */ - public boolean readLock(Object key, Object lockedObj) + public boolean readLock(Object key, Object resourceId) { - LockEntry writer = getWriter(lockedObj); - Collection readers = getReaders(lockedObj); + LockEntry writer = getWriter(resourceId); + Collection readers = getReaders(resourceId); if(writer == null) { // only one reader at a time if(readers.size() == 0) { - if(addReader(key, lockedObj, ISOLATION_LEVEL)) + if(addReader(key, resourceId, ISOLATION_LEVEL)) { - readers = getReaders(lockedObj); + readers = getReaders(resourceId); if(readers.size() == 1) { return true; } else { - removeReader(key, lockedObj); - return readLock(key, lockedObj); + removeReader(key, resourceId); + return readLock(key, resourceId); } } else - return readLock(key, lockedObj); + return readLock(key, resourceId); } else if((readers.size() == 1) && (((LockEntry) readers.iterator().next()).isOwnedBy(key))) { @@ -79,24 +79,24 @@ /** * @see LockStrategy#writeLock(java.lang.Object, java.lang.Object) */ - public boolean writeLock(Object key, Object lockedObj) + public boolean writeLock(Object key, Object resourceId) { - LockEntry writer = getWriter(lockedObj); - Collection readers = getReaders(lockedObj); + LockEntry writer = getWriter(resourceId); + Collection readers = getReaders(resourceId); if(writer == null) { if(readers.size() == 0) { - if(setWriter(key, lockedObj, ISOLATION_LEVEL)) + if(setWriter(key, resourceId, ISOLATION_LEVEL)) return true; else - return writeLock(key, lockedObj); + return writeLock(key, resourceId); } else if(readers.size() == 1) { if(((LockEntry) readers.iterator().next()).isOwnedBy(key)) - return upgradeLock(key, lockedObj); + return upgradeLock(key, resourceId); } } else if(writer.isOwnedBy(key)) @@ -109,12 +109,12 @@ /** * @see LockStrategy#upgradeLock(java.lang.Object, java.lang.Object) */ - public boolean upgradeLock(Object key, Object lockedObj) + public boolean upgradeLock(Object key, Object resourceId) { - LockEntry writer = getWriter(lockedObj); + LockEntry writer = getWriter(resourceId); if(writer == null) { - Collection readers = getReaders(lockedObj); + Collection readers = getReaders(resourceId); if(readers.size() == 1) { LockEntry reader = (LockEntry) readers.iterator().next(); @@ -123,17 +123,17 @@ if(upgradeLock(reader)) return true; else - return upgradeLock(key, lockedObj); + return upgradeLock(key, resourceId); } } else { if(readers.size() == 0) { - if(setWriter(key, lockedObj, ISOLATION_LEVEL)) + if(setWriter(key, resourceId, ISOLATION_LEVEL)) return true; else - return upgradeLock(key, lockedObj); + return upgradeLock(key, resourceId); } } } @@ -148,35 +148,39 @@ /** * @see LockStrategy#readLock(java.lang.Object, java.lang.Object) */ - public boolean releaseLock(Object key, Object lockedObj) + public boolean releaseLock(Object key, Object resourceId) { - LockEntry writer = getWriter(lockedObj); + LockEntry writer = getWriter(resourceId); + boolean result = false; +// if(writer != null && writer.isOwnedBy(key)) +// { +// removeWriter(writer); +// result = true; +// } +// +// if(hasReadLock(key, resourceId)) +// { +// removeReader(key, resourceId); +// result = true; +// } if(writer != null && writer.isOwnedBy(key)) { - removeWriter(writer); - return true; - } - - if(hasReadLock(key, lockedObj)) - { - removeReader(key, lockedObj); - return true; + result = removeWriter(writer); } - else - return false; - + if(removeReader(key, resourceId)) result = true; + return result; } /** * @see LockStrategy#checkRead(java.lang.Object, java.lang.Object) */ - public boolean checkRead(Object key, Object lockedObj) + public boolean checkRead(Object key, Object resourceId) { - if(hasReadLock(key, lockedObj)) + if(hasReadLock(key, resourceId)) { return true; } - LockEntry writer = getWriter(lockedObj); + LockEntry writer = getWriter(resourceId); if(writer != null && writer.isOwnedBy(key)) { return true; @@ -188,9 +192,9 @@ /** * @see LockStrategy#checkWrite(java.lang.Object, java.lang.Object) */ - public boolean checkWrite(Object key, Object lockedObj) + public boolean checkWrite(Object key, Object resourceId) { - LockEntry writer = getWriter(lockedObj); + LockEntry writer = getWriter(resourceId); return (writer != null && writer.isOwnedBy(key)); } } 1.3 +37 -31 db-ojb/src/java/org/apache/ojb/broker/locking/RepeatableReadStrategy.java Index: RepeatableReadStrategy.java =================================================================== RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/locking/RepeatableReadStrategy.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- RepeatableReadStrategy.java 20 Sep 2004 14:32:26 -0000 1.2 +++ RepeatableReadStrategy.java 11 Nov 2004 23:39:01 -0000 1.3 @@ -41,15 +41,15 @@ /** * @see LockStrategy#readLock(java.lang.Object, java.lang.Object) */ - public boolean readLock(Object key, Object lockedObj) + public boolean readLock(Object key, Object resourceId) { - LockEntry writer = getWriter(lockedObj); + LockEntry writer = getWriter(resourceId); if(writer == null) { - if(addReader(key, lockedObj, ISOLATION_LEVEL)) + if(addReader(key, resourceId, ISOLATION_LEVEL)) return true; else - return readLock(key, lockedObj); + return readLock(key, resourceId); } if(writer.isOwnedBy(key)) { @@ -63,24 +63,24 @@ /** * @see LockStrategy#writeLock(java.lang.Object, java.lang.Object) */ - public boolean writeLock(Object key, Object lockedObj) + public boolean writeLock(Object key, Object resourceId) { - LockEntry writer = getWriter(lockedObj); - Collection readers = getReaders(lockedObj); + LockEntry writer = getWriter(resourceId); + Collection readers = getReaders(resourceId); if(writer == null) { if(readers.size() == 0) { - if(setWriter(key, lockedObj, ISOLATION_LEVEL)) + if(setWriter(key, resourceId, ISOLATION_LEVEL)) return true; else - return writeLock(key, lockedObj); + return writeLock(key, resourceId); } else if(readers.size() == 1) { if(((LockEntry) readers.iterator().next()).isOwnedBy(key)) - return upgradeLock(key, lockedObj); + return upgradeLock(key, resourceId); } } else if(writer.isOwnedBy(key)) @@ -94,12 +94,12 @@ /** * @see LockStrategy#upgradeLock(java.lang.Object, java.lang.Object) */ - public boolean upgradeLock(Object key, Object lockedObj) + public boolean upgradeLock(Object key, Object resourceId) { - LockEntry writer = getWriter(lockedObj); + LockEntry writer = getWriter(resourceId); if(writer == null) { - Collection readers = this.getReaders(lockedObj); + Collection readers = this.getReaders(resourceId); if(readers.size() == 1) { LockEntry reader = (LockEntry) readers.iterator().next(); @@ -108,15 +108,15 @@ if(upgradeLock(reader)) return true; else - return upgradeLock(key, lockedObj); + return upgradeLock(key, resourceId); } } else if(readers.size() == 0) { - if(setWriter(key, lockedObj, ISOLATION_LEVEL)) + if(setWriter(key, resourceId, ISOLATION_LEVEL)) return true; else - return upgradeLock(key, lockedObj); + return upgradeLock(key, resourceId); } @@ -132,32 +132,38 @@ /** * @see LockStrategy#readLock(java.lang.Object, java.lang.Object) */ - public boolean releaseLock(Object key, Object lockedObj) + public boolean releaseLock(Object key, Object resourceId) { - LockEntry writer = getWriter(lockedObj); + LockEntry writer = getWriter(resourceId); + boolean result = false; +// if(writer != null && writer.isOwnedBy(key)) +// { +// removeWriter(writer); +// result = true; +// } +// if(hasReadLock(key, resourceId)) +// { +// removeReader(key, resourceId); +// result = true; +// } if(writer != null && writer.isOwnedBy(key)) { - removeWriter(writer); - return true; + result = removeWriter(writer); } - if(hasReadLock(key, lockedObj)) - { - removeReader(key, lockedObj); - return true; - } - return false; + if(removeReader(key, resourceId)) result = true; + return result; } /** * @see LockStrategy#checkRead(java.lang.Object, java.lang.Object) */ - public boolean checkRead(Object key, Object lockedObj) + public boolean checkRead(Object key, Object resourceId) { - if(hasReadLock(key, lockedObj)) + if(hasReadLock(key, resourceId)) { return true; } - LockEntry writer = getWriter(lockedObj); + LockEntry writer = getWriter(resourceId); if(writer != null && writer.isOwnedBy(key)) { return true; @@ -169,9 +175,9 @@ /** * @see LockStrategy#checkWrite(java.lang.Object, java.lang.Object) */ - public boolean checkWrite(Object key, Object lockedObj) + public boolean checkWrite(Object key, Object resourceId) { - LockEntry writer = getWriter(lockedObj); + LockEntry writer = getWriter(resourceId); return (writer != null && writer.isOwnedBy(key)); } } --------------------------------------------------------------------- To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org For additional commands, e-mail: ojb-dev-help@db.apache.org