db-ojb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From arm...@apache.org
Subject svn commit: r373133 - /db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/TransactionImpl.java
Date Sat, 28 Jan 2006 11:00:53 GMT
Author: arminw
Date: Sat Jan 28 03:00:46 2006
New Revision: 373133

URL: http://svn.apache.org/viewcvs?rev=373133&view=rev
Log:
use IdentityArrayList for proxy objects to avoid materialization
optimize tx.commit call
adopt refactored locking

Modified:
    db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/TransactionImpl.java

Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/TransactionImpl.java
URL: http://svn.apache.org/viewcvs/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/TransactionImpl.java?rev=373133&r1=373132&r2=373133&view=diff
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/TransactionImpl.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/TransactionImpl.java Sat
Jan 28 03:00:46 2006
@@ -42,12 +42,14 @@
 import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
 import org.apache.ojb.broker.util.BrokerHelper;
 import org.apache.ojb.broker.util.GUIDFactory;
+import org.apache.ojb.broker.util.IdentityArrayList;
 import org.apache.ojb.broker.util.configuration.Configurable;
 import org.apache.ojb.broker.util.configuration.Configuration;
 import org.apache.ojb.broker.util.configuration.ConfigurationException;
 import org.apache.ojb.broker.util.logging.Logger;
 import org.apache.ojb.broker.util.logging.LoggerFactory;
 import org.apache.ojb.odmg.locking.LockManager;
+import org.apache.ojb.odmg.locking.LockManagerOdmgImpl;
 import org.odmg.DatabaseClosedException;
 import org.odmg.LockNotGrantedException;
 import org.odmg.ODMGRuntimeException;
@@ -93,7 +95,7 @@
      * the internal table containing all Objects "touched" by this tx and their
      * respective transactional state
      */
-    protected final ObjectEnvelopeTable objectEnvelopeTable;
+    public final ObjectEnvelopeTable objectEnvelopeTable;
 
     /**
      * reference to the currently opened database
@@ -106,17 +108,22 @@
      */
     private ArrayList registeredIndirectionHandlers = new ArrayList();
 
+    /*
+    arminw:
+    in both cases below we have to use identity based lists, because normal
+    lists will call obj.equals(...) which will materialize the proxy object
+    */
     /**
      * Unloaded collection proxies which will be registered with tx when
      * collection is loaded
      */
-    private ArrayList registeredCollectionProxies = new ArrayList();
+    private IdentityArrayList registeredCollectionProxies = new IdentityArrayList();
 
     /**
      * list of proxy objects that were locked, but haven't been materialized yet.
      * This is necessary so the locks can be released on closing the transaction
      */
-    private ArrayList unmaterializedLocks = new ArrayList();
+    private IdentityArrayList unmaterializedLocks = new IdentityArrayList();
 
     /**
      * This list is used to avoid endless loops on circular referenced objects.
@@ -259,7 +266,7 @@
      * Lock and register the specified object, make sure that when cascading locking and
register
      * is enabled to specify a List to register the already processed object Identiy.
      */
-    private void internalLockRegister(RuntimeObject rtObject, int lockMode, boolean cascade)
+    private void internalLockRegister(final RuntimeObject rtObject, final int lockMode, final
boolean cascade)
     {
         if(log.isDebugEnabled()) log.debug("Lock and register called for " + rtObject.getIdentity());
         // if current object was already locked, do nothing
@@ -301,8 +308,9 @@
                 else
                 {
                     registerToIndirectionHandler(handler);
-                    registerUnmaterializedLocks(rtObject);
-                    // all work is done, so set to null
+                    lockUnmaterializedObject(rtObject, lockMode);
+                    // all work is done, so set to null to skip
+                    // "normal" registration/lock below
                     objectToRegister = null;
                 }
             }
@@ -322,7 +330,7 @@
                     // we don't need to lock new objects
                     if(!rtObject.isNew())
                     {
-                        internalSingleLock(rtObject.getCld(), rtObject.getObj(), rtObject.getIdentity(),
lockMode);
+                        internalSingleLock(rtObject.getCld(), rtObject.getIdentity(), lockMode);
                     }
                     // after we locked the object, register it to detect status and changes
while tx
                     internalSingleRegister(rtObject, lockMode);
@@ -332,7 +340,7 @@
                     //log.error("Locking of obj " + rtObject.getIdentity() + " failed", t);
                     // if registering of object fails release lock on object, because later
we don't
                     // get a change to do this.
-                    implementation.getLockManager().releaseLock(this, rtObject.getIdentity(),
rtObject.getObj());
+                    implementation.getLockManager().releaseLock(this, rtObject.getIdentity());
                     if(t instanceof LockNotGrantedException)
                     {
                         throw (LockNotGrantedException) t;
@@ -385,7 +393,7 @@
      *
      * @exception  LockNotGrantedException    Description of Exception
      */
-    void internalSingleLock(ClassDescriptor cld, Object obj, Identity oid, int lockMode)
throws LockNotGrantedException
+    void internalSingleLock(final ClassDescriptor cld, final Identity oid, final int lockMode)
throws LockNotGrantedException
     {
         LockManager lm = implementation.getLockManager();
         if (cld.isAcceptLocks())
@@ -393,7 +401,7 @@
             if (lockMode == Transaction.READ)
             {
                 if (log.isDebugEnabled()) log.debug("Do READ lock on object: " + oid);
-                if(!lm.readLock(this, oid, obj))
+                if(!lm.readLock(this, oid, cld))
                 {
                     throw new LockNotGrantedException("Can not lock for READ: " + oid);
                 }
@@ -401,7 +409,7 @@
             else if (lockMode == Transaction.WRITE)
             {
                 if (log.isDebugEnabled()) log.debug("Do WRITE lock on object: " + oid);
-                if(!lm.writeLock(this, oid, obj))
+                if(!lm.writeLock(this, oid, cld))
                 {
                     throw new LockNotGrantedException("Can not lock for WRITE: " + oid);
                 }
@@ -409,7 +417,7 @@
             else if (lockMode == Transaction.UPGRADE)
             {
                 if (log.isDebugEnabled()) log.debug("Do UPGRADE lock on object: " + oid);
-                if(!lm.upgradeLock(this, oid, obj))
+                if(!lm.upgradeLock(this, oid, cld))
                 {
                     throw new LockNotGrantedException("Can not lock for UPGRADE: " + oid);
                 }
@@ -489,24 +497,21 @@
     {
         try
         {
-            LockManager lm = getImplementation().getLockManager();
-            Enumeration en = objectEnvelopeTable.elements();
-            while (en.hasMoreElements())
+            try
             {
-                ObjectEnvelope oe = (ObjectEnvelope) en.nextElement();
-                lm.releaseLock(this, oe.getIdentity(), oe.getObject());
+                // this tx is no longer interested in materialization callbacks
+                unRegisterFromAllIndirectionHandlers();
+                unRegisterFromAllCollectionProxies();
             }
-
-            //remove locks for objects which haven't been materialized yet
-            for (Iterator it = unmaterializedLocks.iterator(); it.hasNext();)
+            catch(Exception e)
             {
-                RuntimeObject rt = (RuntimeObject) it.next();
-                lm.releaseLock(this, rt.getIdentity(), rt.getObj());
+                log.error("Unexpected error while unregister transaction from proxy listener",
e);
             }
 
-            // this tx is no longer interested in materialization callbacks
-            unRegisterFromAllIndirectionHandlers();
-            unRegisterFromAllCollectionProxies();
+            LockManager lm = getImplementation().getLockManager();
+            // this call is important to unlock registered
+            // objects and unregistered proxies
+            lm.releaseLocks(this);
         }
         finally
         {
@@ -537,6 +542,7 @@
         // could be used several times
         broker = null;
         if(unmaterializedLocks.size() > 0) unmaterializedLocks.clear();
+        txStatus = Status.STATUS_NO_TRANSACTION;
     }
 
     /**
@@ -716,6 +722,11 @@
         }
     }
 
+    private boolean needFullCommit()
+    {
+        return objectEnvelopeTable.registeredObjectCount() > 0 || namedRootsMap.needsCommit();
+    }
+
     /**
      * Commit and close the transaction. Calling <code>commit</code> commits
to
      * the database all persistent object modifications within the transaction and
@@ -740,13 +751,16 @@
         checkOpen();
         try
         {
-            prepareCommit();
-            checkForCommit();
+            if(needFullCommit())
+            {
+                prepareCommit();
+                checkForCommit();
 
-            txStatus = Status.STATUS_COMMITTING;
-            if (log.isDebugEnabled()) log.debug("Commit transaction " + this);
+                txStatus = Status.STATUS_COMMITTING;
+                if (log.isDebugEnabled()) log.debug("Commit transaction " + this);
+            }
             // now do real commit on broker
-            if(hasBroker()) getBroker().commitTransaction();
+            if(hasBroker() && getBroker().isInTransaction()) getBroker().commitTransaction();
 
             // Now, we notify everything the commit is done.
             performTransactionAwareAfterCommit();
@@ -897,7 +911,7 @@
         txStatus = Status.STATUS_ACTIVE;
     }
 
-    protected void checkForBegin()
+    private void checkForBegin()
     {
         /**
          * Is the associated database non-null and open? ODMG 3.0 says it must be.
@@ -989,7 +1003,7 @@
      * reference locking, we will materialize objects and they will enter the registered
for
      * lock map.
      */
-    private void internalLockRegisterReferences(ClassDescriptor cld, Object sourceObject,
int lockMode, boolean cascade) throws LockNotGrantedException
+    private void internalLockRegisterReferences(final ClassDescriptor cld, final Object sourceObject,
final int lockMode, final boolean cascade) throws LockNotGrantedException
     {
         if (implicitLocking)
         {
@@ -1008,7 +1022,7 @@
         }
     }
 
-    private void internalLockRegisterCollections(ClassDescriptor cld, Object sourceObject,
int lockMode, boolean cascade) throws LockNotGrantedException
+    private void internalLockRegisterCollections(final ClassDescriptor cld, final Object
sourceObject, final int lockMode, boolean cascade) throws LockNotGrantedException
     {
         if (implicitLocking)
         {
@@ -1155,12 +1169,41 @@
     }
 
     /**
-     * register proxy objects that were locked but haven't been materialized yet
-     * so they can be unlocked when closing the transaction
+     * Lock unmaterialized proxy objects -
+     *
+     * @param rtObj The unmaterialized proxy.
+     * @param lockMode The lock mode.
      */
-    protected void registerUnmaterializedLocks(RuntimeObject rtObj)
+    private void lockUnmaterializedObject(final RuntimeObject rtObj, final int lockMode)
     {
+        // TODO: remove this list when deprecated locking classes are removed
         unmaterializedLocks.add(rtObj);
+        if(log.isDebugEnabled()) log.debug("Lock unmaterialized proxy object: " + rtObj.getIdentity());
+        internalSingleLock(rtObj.getCld(), rtObj.getIdentity(), lockMode);
+    }
+
+    /**
+     * For internal use! For backward compatibility with older
+     * locking implementations. This methods releases all locks for
+     * unmaterialized objects which are not registered in {@link ObjectEnvelopeTable}.
+     * The new lock implementation fully supports methods
+     * {@link org.apache.ojb.odmg.locking.LockManager#releaseLocks(org.apache.ojb.odmg.TransactionImpl)}
+     * the old ones need this method.
+     * @deprecated will be removed
+     */
+    public void releaseUnmaterialzedLocks()
+    {
+        // TODO: remove this method when deprecated locking classes are removed
+        LockManager lm = getImplementation().getLockManager();
+        if(!(lm instanceof LockManagerOdmgImpl))
+        {
+            //remove locks for objects which haven't been materialized yet
+            for (Iterator it = unmaterializedLocks.iterator(); it.hasNext();)
+            {
+                RuntimeObject rt = (RuntimeObject) it.next();
+                lm.releaseLock(this, rt.getIdentity());
+            }
+        }
     }
 
     /**



---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


Mime
View raw message