You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-dev@db.apache.org by ol...@apache.org on 2003/06/17 00:47:27 UTC

cvs commit: db-ojb/src/java/org/apache/ojb/otm/swizzle CopySwizzling.java Swizzling.java

olegnitz    2003/06/16 15:47:27

  Modified:    src/java/org/apache/ojb/otm OTMConnection.java
               src/java/org/apache/ojb/otm/core BaseConnection.java
                        ConcreteEditingContext.java RequestContext.java
               src/java/org/apache/ojb/otm/lock IsolationFactory.java
               src/java/org/apache/ojb/otm/swizzle CopySwizzling.java
                        Swizzling.java
  Log:
  Implemented getIteratorByQuery() and invalidate() in OTMConnection
  
  Revision  Changes    Path
  1.5       +54 -16    db-ojb/src/java/org/apache/ojb/otm/OTMConnection.java
  
  Index: OTMConnection.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/otm/OTMConnection.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- OTMConnection.java	9 Jun 2003 18:55:26 -0000	1.4
  +++ OTMConnection.java	16 Jun 2003 22:47:26 -0000	1.5
  @@ -54,8 +54,10 @@
    * <http://www.apache.org/>.
    */
   
  +import java.util.Iterator;
   import org.apache.ojb.broker.Identity;
   import org.apache.ojb.broker.metadata.ClassDescriptor;
  +import org.apache.ojb.broker.query.Query;
   import org.apache.ojb.otm.lock.LockingException;
   
   /**
  @@ -69,20 +71,16 @@
   
       /**
        *
  +     * Make the given object persistent by inserting it into the database.
  +     * Also read locks the object (OTM will automatically lock
  +     * it for write on transaction commit if the object will appear
  +     * to be modified).
        *
  -     *
  -     */
  -    public void invalidate(Identity oid);
  -
  -    /**
  -     *
  -     *  Make the given object persistent by inserting it into the database.
  -     *
  -     *  @param object       the object to be made persistent
  +     * @param object       the object to be made persistent
        *
        */
       public void makePersistent(Object object)
  -        throws LockingException;
  +            throws LockingException;
   
       /**
        *
  @@ -93,7 +91,7 @@
        *
        */
       public void deletePersistent(Object obj)
  -        throws LockingException;
  +            throws LockingException;
   
       /**
        *
  @@ -104,12 +102,13 @@
        *
        */
       public void lockForWrite(Object object)
  -        throws LockingException;
  +            throws LockingException;
   
       /**
        *
        *  Get the object with the given Identity from the persistent store. By default, the fetch is
  -     *  for read.
  +     *  for read. (OTM will automatically lock it for write on transaction commit 
  +     * if the object will appear to be modified).
        *
        *  @param oid                  the Identity of the object to fetch
        *  @return                     the object from the persistent store.
  @@ -118,7 +117,7 @@
        *
        */
       public Object getObjectByIdentity(Identity oid)
  -        throws LockingException;
  +            throws LockingException;
   
       /**
        *
  @@ -126,12 +125,38 @@
        *
        * @param oid                   the Identity of the object to fetch
        * @param lock                  the lock that need to be acquired on the object
  -     *  @return                     the object from the persistent store.
  +     * Possible values are:
  +     * LockType.NO_LOCK (aka read only) - changes to the object will not be written to database;
  +     * LockType.READ_LOCK (aka optimistic lock) - changes to the object will be written to the database,
  +     * in this case the lock will be automatically upgraded to the write lock on transaction commit;
  +     * LockType.WRITE_LOCK (aka pessimistic lock) - changes to the object will be written to the database.
  +     *
  +     * @return                     the object from the persistent store.
        * @throws LockingException     thrown by the LockManager to avoid a deadlock.
        *
        */
       public Object getObjectByIdentity(Identity oid, int lock)
  -        throws LockingException;
  +            throws LockingException;
  +
  +    /**
  +     * @param query The query to execute
  +     * @return an Iterator that iterates Objects of class c if calling the .next()
  +     * method. The returned objects are locked for read.
  +     */
  +    public Iterator getIteratorByQuery(Query query);
  +
  +    /**
  +     * @param query The query to execute
  +     * @param lock the lock that need to be acquired on the object
  +     * Possible values are:
  +     * LockType.NO_LOCK (aka read only) - changes to the object will not be written to database;
  +     * LockType.READ_LOCK (aka optimistic lock) - changes to the object will be written to the database,
  +     * in this case the lock will be automatically upgraded to the write lock on transaction commit;
  +     * LockType.WRITE_LOCK (aka pessimistic lock) - changes to the object will be written to the database.
  +     * @return an Iterator that iterates Objects of class c if calling the .next()
  +     * method. The returned objects are locked with the given lock value.
  +     */
  +    public Iterator getIteratorByQuery(Query query, int lock);
   
       /**
        * Get the identity of the object
  @@ -152,4 +177,17 @@
        *
        */
       public EditingContext getEditingContext();
  +    
  +    /**
  +     * In the case if the program need to change the objects
  +     * via direct JDBC call, it should first call invalidate() 
  +     * for the object, which will lock the object for write 
  +     * and tell OJB OTM that it must be re-read from the database,
  +     * only after that you shold perform JDBC operation.
  +     * NOTE: it is not recommended to use read-uncommitted isolation
  +     * if you want this feature to work correctly.
  +     */
  +    public void invalidate(Identity oid)
  +            throws LockingException;
  +
   }
  
  
  
  1.10      +95 -44    db-ojb/src/java/org/apache/ojb/otm/core/BaseConnection.java
  
  Index: BaseConnection.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/otm/core/BaseConnection.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- BaseConnection.java	16 Jun 2003 16:17:56 -0000	1.9
  +++ BaseConnection.java	16 Jun 2003 22:47:26 -0000	1.10
  @@ -54,15 +54,19 @@
    * <http://www.apache.org/>.
    */
   
  +import java.util.Iterator;
   import org.apache.ojb.broker.Identity;
   import org.apache.ojb.broker.PBKey;
   import org.apache.ojb.broker.PersistenceBroker;
  +import org.apache.ojb.broker.accesslayer.OJBIterator;
   import org.apache.ojb.broker.cache.ObjectCache;
  -import org.apache.ojb.broker.metadata.ClassDescriptor;
   import org.apache.ojb.broker.core.PersistenceBrokerImpl;
   import org.apache.ojb.broker.core.PersistenceBrokerFactoryFactory;
  +import org.apache.ojb.broker.metadata.ClassDescriptor;
  +import org.apache.ojb.broker.query.Query;
   import org.apache.ojb.otm.EditingContext;
   import org.apache.ojb.otm.OTMConnection;
  +import org.apache.ojb.otm.lock.LockManager;
   import org.apache.ojb.otm.lock.LockType;
   import org.apache.ojb.otm.lock.LockingException;
   
  @@ -78,7 +82,7 @@
   {
   
       private PersistenceBroker _kernel;
  -    private Transaction _transaction;
  +    private Transaction _tx;
       private RequestContext _requestContext;
       private ConcreteEditingContext _editingContext;
   
  @@ -103,22 +107,22 @@
           {
               _editingContext = null;
           }
  -        else if (_transaction != null)
  +        else if (_tx != null)
           {
               throw new IllegalStateException(
                       "OTMConnection is already bound to the transactaction "
  -                    + _transaction);
  +                    + _tx);
           }
           else
           {
               _editingContext = new ConcreteEditingContext(transaction, _kernel);
           }
  -        _transaction = transaction;
  +        _tx = transaction;
       }
   
       public Transaction getTransaction()
       {
  -        return _transaction;
  +        return _tx;
       }
   
   
  @@ -134,23 +138,8 @@
       {
           Object object;
   
  -        establishContext(lock);
  -
  -        try
  -        {
  -            try
  -            {
  -                object = getKernelBroker().getObjectByIdentity(oid);
  -            }
  -            catch (LockingPassthruException lockingPassthruException)
  -            {
  -                throw lockingPassthruException.getLockingException();
  -            }
  -        }
  -        finally
  -        {
  -            releaseContext();
  -        }
  +        object = _kernel.getObjectByIdentity(oid);
  +        _editingContext.insert(oid, object, lock);
           return object;
       }
   
  @@ -164,6 +153,33 @@
       }
   
       /**
  +     * @param query The query to execute
  +     * @return an Iterator that iterates Objects of class c if calling the .next()
  +     * method. The returned objects are locked for read.
  +     */
  +    public Iterator getIteratorByQuery(Query query)
  +    {
  +        return getIteratorByQuery(query, LockType.READ_LOCK);
  +    }
  +
  +    /**
  +     * @param query The query to execute
  +     * @param lock the lock that need to be acquired on the object
  +     * Possible values are:
  +     * LockType.NO_LOCK (aka read only) - changes to the object will not be written to database;
  +     * LockType.READ_LOCK (aka optimistic lock) - changes to the object will be written to the database,
  +     * in this case the lock will be automatically upgraded to the write lock on transaction commit;
  +     * LockType.WRITE_LOCK (aka pessimistic lock) - changes to the object will be written to the database.
  +     * @return an Iterator that iterates Objects of class c if calling the .next()
  +     * method. The returned objects are locked with the given lock value.
  +     */
  +    public Iterator getIteratorByQuery(Query query, int lock)
  +    {
  +        return new LockingIterator(_kernel.getIteratorByQuery(query), lock);
  +    }
  +
  +
  +    /**
        * Get the identity of the object
        * @param object The object
        * @return the identity of the object
  @@ -187,7 +203,16 @@
        * @see org.apache.ojb.otm.OTMConnection#invalidate(Identity)
        */
       public void invalidate(Identity oid)
  +            throws LockingException
       {
  +        LockManager lockManager = LockManager.getInstance();
  +
  +        // lock for write and mark as invalidated in the editing context
  +        _editingContext.insert(oid, null, LockType.WRITE_LOCK);
  +
  +        // remove from the cache
  +        _tx.getKit().getGlobalCache().evict(oid);
  +
       }
   
       /**
  @@ -246,7 +271,7 @@
        *  Prepare for a commit. As part of a two phase commit protocol of the transaction.
        *
        */
  -    public abstract void transactionPrepare() 
  +    public abstract void transactionPrepare()
               throws TransactionException;
   
       /**
  @@ -283,26 +308,6 @@
   
   
       ///////////////////////////////////////
  -    // Private Operations
  -    ///////////////////////////////////////
  -
  -    private void establishContext(int lock)
  -    {
  -        if (_requestContext.isInUse())
  -        {
  -            throw new ConnectionException(
  -                "Cannot use a connection concurrently across multiple threads");
  -        }
  -        _requestContext.establishContext(lock);
  -    }
  -
  -
  -    private void releaseContext ()
  -    {
  -        _requestContext.releaseContext();
  -    }
  -
  -    ///////////////////////////////////////
       // Inner classes
       ///////////////////////////////////////
   
  @@ -318,6 +323,52 @@
           public void setObjectCache(ObjectCache cache)
           {
               objectCache = cache;
  +        }
  +    }
  +
  +    private class LockingIterator implements Iterator
  +    {
  +        private final Iterator _it;
  +        private final int _lock;
  +
  +        LockingIterator(Iterator it, int lock)
  +        {
  +            _it = it;
  +            _lock = lock;
  +        }
  +
  +        public boolean hasNext()
  +        {
  +            boolean res = _it.hasNext();
  +
  +            // once the result set is finished, close it
  +            if (!res && (_it instanceof OJBIterator))
  +            {
  +                ((OJBIterator) _it).releaseDbResources();
  +            }
  +
  +            return res;
  +        }
  +
  +        public Object next()
  +        {
  +            Object object;
  +
  +            object = _it.next();
  +            try 
  +            {
  +                _editingContext.insert(getIdentity(object), object, _lock);
  +            }
  +            catch (LockingException ex)
  +            {
  +                throw new LockingPassthruException(ex);
  +            }
  +            return object;
  +        }
  +
  +        public void remove()
  +        {
  +            throw new UnsupportedOperationException();
           }
       }
   }
  
  
  
  1.13      +14 -23    db-ojb/src/java/org/apache/ojb/otm/core/ConcreteEditingContext.java
  
  Index: ConcreteEditingContext.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/otm/core/ConcreteEditingContext.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- ConcreteEditingContext.java	16 Jun 2003 16:17:56 -0000	1.12
  +++ ConcreteEditingContext.java	16 Jun 2003 22:47:26 -0000	1.13
  @@ -163,12 +163,13 @@
               LockManager lockManager = LockManager.getInstance();
               Swizzling swizzlingStrategy = kit.getSwizzlingStrategy();
   
  -                // A similar or the same object is present in the context
  +            // A similar or the same object is present in the context
               Object oldObj = entry.object;
  +
               if (swizzlingStrategy.isSameInstance(oldObj, newObj))
               {
  -                    // The object in context is the same object attempted an insert on
  -                    // Ensure we have the correct lock level
  +                // The object in context is the same object attempted an insert on
  +                // Ensure we have the correct lock level
                   lockManager.ensureLock(oid, _tx, lock, _pb);
               }
               else
  @@ -178,13 +179,13 @@
                   entry.object = swizzlingStrategy.swizzle(newObj, oldObj, _pb);
               }
           }
  -        
  +
           if (!_order.contains(oid)) {
               _order.add(oid);
   
               // perform automatic read lock for all reachable objects
               // if the inserted object is materialized
  -            if (kit.isImplicitLockingUsed())
  +            if ((newObj != null) && kit.isImplicitLockingUsed())
               {
                   IndirectionHandler handler = getIndirectionHandler(newObj);
   
  @@ -232,23 +233,6 @@
           return (entry == null ? null : entry.object);
       }
   
  -    public Object getFromGlobalCache(Identity oid, int lock)
  -            throws LockingException
  -    {
  -        Object object = _tx.getKit().getGlobalCache().lookup(oid);
  -
  -        if (object != null)
  -        {
  -            ContextEntry entry = (ContextEntry) _objects.get(oid);
  -            
  -            if (entry == null) 
  -            {
  -                insertInternal(oid, object, lock);
  -            }
  -        }
  -
  -        return object;
  -    }
   
       //////////////////////////////////////////
       // MaterializationListener interface
  @@ -328,7 +312,14 @@
                   Identity oid = lockOrder[i];
                   ContextEntry entry = (ContextEntry) _objects.get(oid);
                   State state = entry.state;
  -                IndirectionHandler handler = getIndirectionHandler(entry.object);
  +                IndirectionHandler handler;
  +
  +                if (entry.object == null) // invalidated
  +                {
  +                    continue;
  +                }
  +
  +                handler = getIndirectionHandler(entry.object);
   
                   if (handler == null || handler.alreadyMaterialized())
                   {
  
  
  
  1.11      +9 -75     db-ojb/src/java/org/apache/ojb/otm/core/RequestContext.java
  
  Index: RequestContext.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/otm/core/RequestContext.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- RequestContext.java	16 Jun 2003 16:17:56 -0000	1.10
  +++ RequestContext.java	16 Jun 2003 22:47:26 -0000	1.11
  @@ -71,64 +71,13 @@
   public class RequestContext
       implements ObjectCache
   {
  -    private BaseConnection _connection;
  -    private int _requestedLockType;
  -    private boolean _inUse;
  +    private BaseConnection _conn;
   
  -    public RequestContext(BaseConnection connection)
  +    public RequestContext(BaseConnection conn)
       {
  -        _connection = connection;
  -        _inUse = false;
  +        _conn = conn;
       }
   
  -
  -    /**
  -     *
  -     * Returns the connection.
  -     *
  -     * @return the connection in context
  -     *
  -     */
  -    public BaseConnection getConnection()
  -    {
  -        return _connection;
  -    }
  -
  -    /**
  -     *
  -     * Returns the requestedLockType.
  -     *
  -     * @return the requested Lock type
  -     *
  -     */
  -    public int getRequestedLockType()
  -    {
  -        return _requestedLockType;
  -    }
  -
  -    /**
  -     *
  -     * Establish that the RequestContext is in use.
  -     *
  -     * @param requestedLockType The requestedLockType to set
  -     */
  -    public void establishContext(int requestedLockType)
  -    {
  -        _requestedLockType = requestedLockType;
  -        _inUse = true;
  -    }
  -
  -    public void releaseContext()
  -    {
  -        _inUse = false;
  -    }
  -
  -    public boolean isInUse ()
  -    {
  -        return _inUse;
  -    }
  -
  -
       //////////////////////////////////////////////
       // ObjectCache protocol
       //////////////////////////////////////////////
  @@ -138,7 +87,7 @@
        */
       public void cache(Identity oid, Object obj)
       {
  -        OTMKit kit = _connection.getTransaction().getKit();
  +        OTMKit kit = _conn.getTransaction().getKit();
           kit.getGlobalCache().cache(oid, obj);
       }
   
  @@ -147,8 +96,8 @@
        */
       public void clear()
       {
  -         OTMKit kit = _connection.getTransaction().getKit();
  -         kit.getGlobalCache().evictAll();
  +        OTMKit kit = _conn.getTransaction().getKit();
  +        kit.getGlobalCache().evictAll();
       }
   
       /**
  @@ -156,23 +105,8 @@
        */
       public Object lookup(Identity oid)
       {
  -        int lock = LockType.NO_LOCK;
  -        ConcreteEditingContext editingContext =
  -                (ConcreteEditingContext) _connection.getEditingContext();
  -
  -        if (_inUse)
  -        {
  -            lock = _requestedLockType;
  -        }
  -
  -        try
  -        {
  -            return editingContext.getFromGlobalCache(oid, lock);
  -        }
  -        catch (LockingException ex)
  -        {
  -            throw new LockingPassthruException(ex);
  -        }
  +        OTMKit kit = _conn.getTransaction().getKit();
  +        return kit.getGlobalCache().lookup(oid);
       }
   
       /**
  @@ -180,7 +114,7 @@
        */
       public void remove (Identity oid)
       {
  -         OTMKit kit = _connection.getTransaction().getKit();
  +         OTMKit kit = _conn.getTransaction().getKit();
            kit.getGlobalCache().evict(oid);
       }
   }
  
  
  
  1.9       +1 -1      db-ojb/src/java/org/apache/ojb/otm/lock/IsolationFactory.java
  
  Index: IsolationFactory.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/otm/lock/IsolationFactory.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- IsolationFactory.java	12 Jun 2003 17:28:13 -0000	1.8
  +++ IsolationFactory.java	16 Jun 2003 22:47:27 -0000	1.9
  @@ -108,7 +108,7 @@
                   break;
   
               case IsolationLevels.IL_READ_COMMITTED:
  -                isolation = READ_UNCOMMITTED_ISOLATION;
  +                isolation = READ_COMMITTED_ISOLATION;
                   break;
   
               case IsolationLevels.IL_REPEATABLE_READ:
  
  
  
  1.2       +5 -0      db-ojb/src/java/org/apache/ojb/otm/swizzle/CopySwizzling.java
  
  Index: CopySwizzling.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/otm/swizzle/CopySwizzling.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- CopySwizzling.java	12 Jun 2003 23:41:52 -0000	1.1
  +++ CopySwizzling.java	16 Jun 2003 22:47:27 -0000	1.2
  @@ -20,6 +20,11 @@
        */
       public Object swizzle(Object newObj, Object oldObj, PersistenceBroker pb)
       {
  +        if (newObj == null) // invalidating
  +        {
  +            return null;
  +        }
  +
           if (oldObj == null)
           {
               return newObj;
  
  
  
  1.3       +8 -6      db-ojb/src/java/org/apache/ojb/otm/swizzle/Swizzling.java
  
  Index: Swizzling.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/otm/swizzle/Swizzling.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Swizzling.java	12 Jun 2003 23:40:52 -0000	1.2
  +++ Swizzling.java	16 Jun 2003 22:47:27 -0000	1.3
  @@ -15,13 +15,15 @@
   
       /**
        *
  -     *  Swizzle object references
  +     * Swizzle object references.
        *
  -     *  @param newObj    the object being inserted into the EditingContext
  -     *  @param oldObj    the object present in the EditingContext
  -     *  @param pb        the PersistenceBroker that is used to get
  -     *                   persistent class info
  -     *  @return          the Swizzled Object
  +     * @param newObj    the object being inserted into the EditingContext,
  +     * is null if the object is being invalidated
  +     * @param oldObj    the object present in the EditingContext,
  +     * is null if no object is present
  +     * @param pb        the PersistenceBroker that is used to get
  +     * persistent class info
  +     * @return          the Swizzled Object
        *
        */
       public Object swizzle(Object newObj, Object oldObj, PersistenceBroker pb);