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 [EMAIL PROTECTED]
ObjectEnvelopeTable}.
+ * The new lock implementation fully supports methods
+ * [EMAIL PROTECTED]
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: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]