db-ojb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From arm...@apache.org
Subject cvs commit: db-ojb/src/java/org/apache/ojb/odmg ImplementationImpl.java ImplementationJTAImpl.java J2EETransactionImpl.java ObjectEnvelopeTable.java TransactionAbortedExceptionOJB.java TransactionImpl.java
Date Sat, 27 Nov 2004 23:46:07 GMT
arminw      2004/11/27 15:46:07

  Modified:    src/java/org/apache/ojb/odmg Tag: OJB_1_0_RELEASE
                        ImplementationImpl.java ImplementationJTAImpl.java
                        J2EETransactionImpl.java ObjectEnvelopeTable.java
                        TransactionAbortedExceptionOJB.java
                        TransactionImpl.java
  Log:
  improve exception/tx status handling
  fix problems with abbandoned connections in managed environments
  
  Revision  Changes    Path
  No                   revision
  No                   revision
  1.1.2.2   +8 -7      db-ojb/src/java/org/apache/ojb/odmg/ImplementationImpl.java
  
  Index: ImplementationImpl.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/odmg/ImplementationImpl.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- ImplementationImpl.java	14 Aug 2004 23:42:37 -0000	1.1.2.1
  +++ ImplementationImpl.java	27 Nov 2004 23:46:07 -0000	1.1.2.2
  @@ -69,16 +69,17 @@
           setConfigurator(PersistenceBrokerFactory.getConfigurator());
       }
   
  -    /**
  -     * Method declaration
  -     * @param curDB
  -     */
  +    protected OJBTxManager getTxManager()
  +    {
  +        return ojbTxManager;
  +    }
  +
       protected synchronized void setCurrentDatabase(DatabaseImpl curDB)
       {
           currentDatabase = curDB;
       }
   
  -    public DatabaseImpl getCurrentDatabase()
  +    protected DatabaseImpl getCurrentDatabase()
       {
           return currentDatabase;
       }
  @@ -117,7 +118,7 @@
           {
               throw new DatabaseClosedException("Database is NULL, must have a DB in order
to create a transaction");
           }
  -        TransactionImpl tx = new TransactionImpl(getCurrentDatabase());
  +        TransactionImpl tx = new TransactionImpl(this);
           try
           {
               getConfigurator().configure(tx);
  
  
  
  1.2.2.2   +2 -2      db-ojb/src/java/org/apache/ojb/odmg/ImplementationJTAImpl.java
  
  Index: ImplementationJTAImpl.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/odmg/ImplementationJTAImpl.java,v
  retrieving revision 1.2.2.1
  retrieving revision 1.2.2.2
  diff -u -r1.2.2.1 -r1.2.2.2
  --- ImplementationJTAImpl.java	14 Aug 2004 23:42:37 -0000	1.2.2.1
  +++ ImplementationJTAImpl.java	27 Nov 2004 23:46:07 -0000	1.2.2.2
  @@ -121,7 +121,7 @@
       private J2EETransactionImpl newInternTransaction()
       {
           if (log.isDebugEnabled()) log.debug("obtain new intern odmg-transaction");
  -        J2EETransactionImpl tx = new J2EETransactionImpl(getCurrentDatabase());
  +        J2EETransactionImpl tx = new J2EETransactionImpl(this);
           try
           {
               getConfigurator().configure(tx);
  
  
  
  1.25.2.2  +20 -11    db-ojb/src/java/org/apache/ojb/odmg/J2EETransactionImpl.java
  
  Index: J2EETransactionImpl.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/odmg/J2EETransactionImpl.java,v
  retrieving revision 1.25.2.1
  retrieving revision 1.25.2.2
  diff -u -r1.25.2.1 -r1.25.2.2
  --- J2EETransactionImpl.java	11 Sep 2004 12:20:01 -0000	1.25.2.1
  +++ J2EETransactionImpl.java	27 Nov 2004 23:46:07 -0000	1.25.2.2
  @@ -18,15 +18,17 @@
   import javax.transaction.Status;
   import javax.transaction.Synchronization;
   
  -import org.apache.ojb.broker.OJBRuntimeException;
   import org.apache.ojb.broker.PersistenceBroker;
   import org.apache.ojb.broker.accesslayer.ConnectionManagerIF;
   import org.apache.ojb.broker.util.logging.Logger;
   import org.apache.ojb.broker.util.logging.LoggerFactory;
   import org.odmg.LockNotGrantedException;
  +import org.odmg.ODMGRuntimeException;
   import org.odmg.TransactionAbortedException;
   
   /**
  + * Implementation for use in managed environments.
  + *
    * @author <a href="mailto:mattbaird@yahoo.com">Matthew Baird</a>
    * @version $Id$
    */
  @@ -43,9 +45,9 @@
       private boolean beforeCompletionCall = false;
       private boolean afterCompletionCall = false;
   
  -    public J2EETransactionImpl(DatabaseImpl theCurrentDB)
  +    public J2EETransactionImpl(ImplementationImpl implementation)
       {
  -        super(theCurrentDB);
  +        super(implementation);
           isInExternTransaction = false;
       }
   
  @@ -137,7 +139,7 @@
                       || status == Status.STATUS_NO_TRANSACTION)
               {
                   log.error("Synchronization#beforeCompletion: Can't prepare for commit,
because tx status was "
  -                        + TxUtil.getStatusString(status) + ". Do internal cleanup.");
  +                        + TxUtil.getStatusString(status) + ". Do internal cleanup only.");
               }
               else
               {
  @@ -151,6 +153,7 @@
           }
           catch(Exception e)
           {
  +            log.error("Synchronization#beforeCompletion: Error while prepare for commit",
e);
               if(e instanceof LockNotGrantedException)
               {
                   throw (LockNotGrantedException) e;
  @@ -159,10 +162,14 @@
               {
                   throw (TransactionAbortedException) e;
               }
  -            else
  +            else if(e instanceof ODMGRuntimeException)
               {
  -                new OJBRuntimeException("Method beforeCompletion() fails, status of JTA-tx
was "
  -                        + TxUtil.getStatusString(status), e);
  +                throw (ODMGRuntimeException) e;
  +            }
  +            else
  +            { 
  +                throw new ODMGRuntimeException("Method beforeCompletion() fails, status
of JTA-tx was "
  +                        + TxUtil.getStatusString(status) + ", message: " + e.getMessage());
               }
   
           }
  @@ -207,7 +214,7 @@
       {
           try
           {
  -            // prepareForCommit was done before
  +            // prepare for commit was done before on 'beforeCompleation' call
               if(log.isDebugEnabled()) log.debug("Commit transaction " + this + ", commit
on broker " + broker);
               if(hasBroker())
               {
  @@ -215,11 +222,13 @@
                   doClose();
               }
               setStatus(Status.STATUS_COMMITTED);
  +            // Now, we notify everything the commit is done.
  +            performTransactionAwareAfterCommit();
           }
           catch(Exception ex)
           {
               // We should not reach this block
  -            log.error("Error while commit used PB-Instance and close resources", ex);
  +            log.error("Unexpected error while do commit on used PB-Instance and close resources",
ex);
               abort();
           }
       }
  @@ -239,7 +248,7 @@
                   log.error("Failure while do abort call", ignore);
               }
   
  -            TxManagerFactory.instance().abortExternalTx(this);
  +            getImplementation().getTxManager().abortExternalTx(this);
   
               try
               {
  
  
  
  1.32.2.9  +14 -152   db-ojb/src/java/org/apache/ojb/odmg/ObjectEnvelopeTable.java
  
  Index: ObjectEnvelopeTable.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/odmg/ObjectEnvelopeTable.java,v
  retrieving revision 1.32.2.8
  retrieving revision 1.32.2.9
  diff -u -r1.32.2.8 -r1.32.2.9
  --- ObjectEnvelopeTable.java	20 Nov 2004 17:26:20 -0000	1.32.2.8
  +++ ObjectEnvelopeTable.java	27 Nov 2004 23:46:07 -0000	1.32.2.9
  @@ -16,7 +16,6 @@
    */
   
   import java.util.ArrayList;
  -import java.util.Collections;
   import java.util.Enumeration;
   import java.util.HashMap;
   import java.util.Iterator;
  @@ -45,6 +44,7 @@
   import org.apache.ojb.odmg.locking.LockManagerFactory;
   import org.apache.ojb.odmg.states.StateOldClean;
   import org.odmg.LockNotGrantedException;
  +import org.odmg.ODMGRuntimeException;
   import org.odmg.Transaction;
   import org.odmg.TransactionAbortedException;
   
  @@ -157,21 +157,26 @@
               setCleanState();
   
           }
  -        catch (Throwable t)
  +        catch (Exception e)
           {
  -            // we do that in TransactionImpl#abort()
  -            //            broker.abortTransaction();
               connMan.clearBatch();
  -            log.error("Commit on object level failed for tx " + transaction, t);
  -            if (t instanceof OptimisticLockException)
  +            if(e instanceof OptimisticLockException)
               {
  +                log.warn("Optimistic lock exception while write objects", e);
                   // PB OptimisticLockException should be clearly signalled to the user
  -                Object sourceObject = ((OptimisticLockException) t).getSourceObject();
  -                throw new LockNotGrantedException("(" + sourceObject + ")" + t.getMessage());
  +                Object sourceObject = ((OptimisticLockException) e).getSourceObject();
  +                throw new LockNotGrantedException("Optimistic lock exception occur, source
object was (" + sourceObject + ")," +
  +                        " message was (" + e.getMessage() + ")");
  +            }
  +            else if(!(e instanceof RuntimeException))
  +            {
  +                log.warn("Error while write objects for tx " + transaction, e);
  +                throw new ODMGRuntimeException("Unexpected error while write objects: "
+ e.getMessage());
               }
               else
               {
  -                throw new TransactionAbortedExceptionOJB(t);
  +                log.warn("Error while write objects for tx " + transaction, e);
  +                throw (RuntimeException) e;
               }
           }
           finally
  @@ -434,7 +439,6 @@
       {
           try
           {
  -            PersistenceBroker broker = transaction.getBroker();
               Iterator iter = mvOrderOfIds.iterator();
               while (iter.hasNext())
               {
  @@ -567,148 +571,6 @@
               for (int i = 0; i < newOrder.length; i++)
               {
                   mvOrderOfIds.add(newOrder[i]);
  -            }
  -        }
  -    }
  -       
  -    /**
  -     * put an object and all its dependent objects in the new vector. If the object
  -     * in question is going to be DELETEd, first the objects referenced in collections
  -     * are put in the vector, then the object in question and then the references.
  -     * Otherwise the order is reversed.
  -     */
  -    private void reorderObject(
  -        Map htNewHashtable,
  -        List newVector,
  -        ObjectEnvelope objectToReorder,
  -        Identity id,
  -        Map htOldVectorPosition)
  -        throws IllegalAccessException
  -    {
  -        PersistenceBroker broker = transaction.getBroker();
  -        if (objectToReorder != null)
  -        {
  -            ClassDescriptor cld = broker.getClassDescriptor(objectToReorder.getObject().getClass());
  -            if (objectToReorder.needsDelete())
  -            {
  -                reorderCollection(
  -                    htNewHashtable,
  -                    newVector,
  -                    objectToReorder,
  -                    cld,
  -                    htOldVectorPosition);
  -                newVector.add(id);
  -                htNewHashtable.put(id, objectToReorder);
  -                reorderReference(
  -                    htNewHashtable,
  -                    newVector,
  -                    objectToReorder,
  -                    cld,
  -                    htOldVectorPosition);
  -            }
  -            else
  -            {
  -                reorderReference(
  -                    htNewHashtable,
  -                    newVector,
  -                    objectToReorder,
  -                    cld,
  -                    htOldVectorPosition);
  -                newVector.add(id);
  -                htNewHashtable.put(id, objectToReorder);
  -                reorderCollection(
  -                    htNewHashtable,
  -                    newVector,
  -                    objectToReorder,
  -                    cld,
  -                    htOldVectorPosition);
  -            }
  -        }
  -    }
  -
  -    /**
  -     * Resolves all objects referenced in collections of objectToReorder. The referenced
  -     * objects are removed from the list of modified objects in this class and passed
  -     * to reorderObject, where dependencies of the object are resolved (i.e. if the referenced
  -     * object contains again collections or references) and it is finally put into the
new order
  -     * vector.
  -     */
  -    private void reorderCollection(
  -        Map htNewHashtable,
  -        List newVector,
  -        ObjectEnvelope objectToReorder,
  -        ClassDescriptor cld,
  -        Map htOldVectorPosition)
  -        throws IllegalAccessException
  -    {
  -        Iterator i;
  -        i = cld.getCollectionDescriptors().iterator();
  -        while (i.hasNext())
  -        {
  -            CollectionDescriptor cds = (CollectionDescriptor) i.next();
  -            Object col = cds.getPersistentField().get(objectToReorder.getObject());
  -            if (col != null)
  -            {
  -                Iterator colIterator;
  -                if (ProxyHelper.isCollectionProxy(col) && !ProxyHelper.getCollectionProxy(col).isLoaded())
  -                {
  -                    colIterator = Collections.EMPTY_LIST.iterator();
  -                }
  -                else
  -                {
  -                    colIterator = BrokerHelper.getCollectionIterator(col);
  -                }
  -                while (colIterator.hasNext())
  -                {
  -                    // The collection now contains all the objects in the collection.
  -                    // Now we have to retrieve the ObjectEnvelope representing this
  -                    // Object from the hashtable, remove it from the vector and reorder
  -                    // the retrieved ObjectEnvelope.
  -                    Identity id = transaction.getBroker().serviceIdentity().buildIdentity(colIterator.next());
  -                    ObjectEnvelope oe = (ObjectEnvelope) mhtObjectEnvelopes.get(id);
  -                    if (oe != null)
  -                    {
  -                        mvOrderOfIds.set(((Integer) htOldVectorPosition.get(id)).intValue(),
null);
  -                        // mvOrderOfIds.set(mvOrderOfIds.indexOf(id), null);
  -                        mhtObjectEnvelopes.remove(id);
  -                        reorderObject(htNewHashtable, newVector, oe, id, htOldVectorPosition);
  -                    }
  -                }
  -            }
  -        }
  -    }
  -
  -    /**
  -     * Resolves all objects referenced in references of objectToReorder. The referenced
  -     * objects are removed from the list of modified objects in this class and passed
  -     * to reorderObject, where dependencies of the object are resolved (i.e. if the referenced
  -     * object contains again collections or references) and it is finally put into the
new order
  -     * vector.
  -     */
  -    private void reorderReference(
  -        Map htNewHashtable,
  -        List newVector,
  -        ObjectEnvelope objectToReorder,
  -        ClassDescriptor cld,
  -        Map htOldVectorPosition)
  -        throws IllegalAccessException
  -    {
  -        Iterator i = cld.getObjectReferenceDescriptors().iterator();
  -        while (i.hasNext())
  -        {
  -            ObjectReferenceDescriptor rds = (ObjectReferenceDescriptor) i.next();
  -            Object refObj = rds.getPersistentField().get(objectToReorder.getObject());
  -            if (refObj != null)
  -            {
  -                Identity id = transaction.getBroker().serviceIdentity().buildIdentity(refObj);
  -                ObjectEnvelope oe = (ObjectEnvelope) mhtObjectEnvelopes.get(id);
  -                if (oe != null)
  -                {
  -                    mhtObjectEnvelopes.remove(id);
  -                    mvOrderOfIds.set(((Integer) htOldVectorPosition.get(id)).intValue(),
null);
  -                    // mvOrderOfIds.set(mvOrderOfIds.indexOf(id), null);
  -                    reorderObject(htNewHashtable, newVector, oe, id, htOldVectorPosition);
  -                }
               }
           }
       }
  
  
  
  1.4.2.1   +34 -27    db-ojb/src/java/org/apache/ojb/odmg/TransactionAbortedExceptionOJB.java
  
  Index: TransactionAbortedExceptionOJB.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/odmg/TransactionAbortedExceptionOJB.java,v
  retrieving revision 1.4
  retrieving revision 1.4.2.1
  diff -u -r1.4 -r1.4.2.1
  --- TransactionAbortedExceptionOJB.java	4 Apr 2004 23:53:38 -0000	1.4
  +++ TransactionAbortedExceptionOJB.java	27 Nov 2004 23:46:07 -0000	1.4.2.1
  @@ -18,11 +18,11 @@
   import org.odmg.TransactionAbortedException;
   
   /**
  - * This specialised exception allows us to capture the cause of an 
  + * This specialised exception allows us to capture the cause of an
    * ODMG TransactionAbortedException. This, in turn,
  - * gives the "catcher" of the exception the ability to take different 
  + * gives the "catcher" of the exception the ability to take different
    * courses of action dependent upon why the transaction was aborted. <p>
  - * This exception has been created as a subclass of 
  + * This exception has been created as a subclass of
    * org.odmg.TransactionAbortedException so that we don't
    * <ul>
    * <li>Modify the ODMG exception - as it is defined by the ODMG spec
  @@ -33,32 +33,39 @@
    */
   public class TransactionAbortedExceptionOJB extends TransactionAbortedException
   {
  -  /**
  -   * The cause of a TransactionAbortedException
  -   */
  -  private Throwable cause;
  +    /**
  +     * The cause of a TransactionAbortedException
  +     */
  +    private Throwable cause;
   
  -  public TransactionAbortedExceptionOJB()
  -  {
  -    super();
  -  }
  +    public TransactionAbortedExceptionOJB()
  +    {
  +        super();
  +    }
   
  -  public TransactionAbortedExceptionOJB(String msg)
  -  {
  -    super(msg);
  -  }
  +    public TransactionAbortedExceptionOJB(String msg)
  +    {
  +        super(msg);
  +    }
   
  -  public TransactionAbortedExceptionOJB(Throwable cause)
  -  {
  -    this.cause = cause;
  -  }
  +    public TransactionAbortedExceptionOJB(String msg, Throwable th)
  +    {
  +        super(msg);
  +        this.cause = th;
  +    }
   
  -  /**
  -   * Returns the cause of the exception. May be null.
  -   * @return
  -   */
  -  public Throwable getCause()
  -  {
  -    return cause;
  -  }
  +    public TransactionAbortedExceptionOJB(Throwable cause)
  +    {
  +        this.cause = cause;
  +    }
  +
  +    /**
  +     * Returns the cause of the exception. May be null.
  +     *
  +     * @return
  +     */
  +    public Throwable getCause()
  +    {
  +        return cause;
  +    }
   }
  
  
  
  1.59.2.7  +177 -127  db-ojb/src/java/org/apache/ojb/odmg/TransactionImpl.java
  
  Index: TransactionImpl.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/odmg/TransactionImpl.java,v
  retrieving revision 1.59.2.6
  retrieving revision 1.59.2.7
  diff -u -r1.59.2.6 -r1.59.2.7
  --- TransactionImpl.java	3 Nov 2004 19:11:47 -0000	1.59.2.6
  +++ TransactionImpl.java	27 Nov 2004 23:46:07 -0000	1.59.2.7
  @@ -28,7 +28,6 @@
   import org.apache.ojb.broker.PersistenceBroker;
   import org.apache.ojb.broker.PersistenceBrokerException;
   import org.apache.ojb.broker.PersistenceBrokerFactory;
  -import org.apache.ojb.broker.PersistenceBrokerSQLException;
   import org.apache.ojb.broker.core.proxy.CollectionProxy;
   import org.apache.ojb.broker.core.proxy.CollectionProxyDefaultImpl;
   import org.apache.ojb.broker.core.proxy.CollectionProxyListener;
  @@ -71,18 +70,18 @@
       private Logger log = LoggerFactory.getLogger(TransactionImpl.class);
       private Hashtable myNrm = null;
       private boolean useWriteLocks;
  -    private boolean useImplicitLocking;
  +    private boolean implicitLocking;
       private String txGUID;
       protected PersistenceBroker broker = null;
       private ArrayList registeredForLock = new ArrayList();
  -    private OJBTxManager txManager;
  +    private ImplementationImpl implementation;
   
       /**
        * The status of the current transaction, as specified by the
        * javax.transaction package.
        * See {@link javax.transaction.Status} for list of valid values.
        */
  -    private int m_txStatus = Status.STATUS_NO_TRANSACTION;
  +    private int txStatus = Status.STATUS_NO_TRANSACTION;
   
       /**
        * the internal table containing all Objects "touched" by this tx and their
  @@ -115,14 +114,19 @@
   
       /**
        * Creates new Transaction
  -     * @param theCurrentDB - create a transaction that is associated with the database.
  +     * @param implementation The odmg Implementation class
        */
  -    public TransactionImpl(DatabaseImpl theCurrentDB)
  +    public TransactionImpl(ImplementationImpl implementation)
       {
  -        txManager = TxManagerFactory.instance();
  +        this.implementation = implementation;
           // assign a globally uniqe id to this tx
           txGUID = new GUID().toString();
  -        curDB = theCurrentDB;
  +        curDB = implementation.getCurrentDatabase();
  +    }
  +
  +    protected ImplementationImpl getImplementation()
  +    {
  +        return implementation;
       }
   
       /**
  @@ -135,12 +139,12 @@
   
       protected int getStatus()
       {
  -        return m_txStatus;
  +        return txStatus;
       }
   
       protected void setStatus(int status)
       {
  -        this.m_txStatus = status;
  +        this.txStatus = status;
       }
   
       private void checkForDB()
  @@ -187,8 +191,8 @@
       public void join()
       {
           checkOpen();
  -        txManager.deregisterTx(this);
  -        txManager.registerTx(this);
  +        implementation.getTxManager().deregisterTx(this);
  +        implementation.getTxManager().registerTx(this);
       }
   
       /**
  @@ -300,7 +304,7 @@
       public void leave()
       {
           checkOpen();
  -        txManager.deregisterTx(this);
  +        implementation.getTxManager().deregisterTx(this);
       }
   
       /**
  @@ -314,17 +318,17 @@
           arminw:
           if broker isn't in PB-tx, start tx
           */
  -        if (log.isDebugEnabled()) log.debug("call beginTransaction() on PB instance");
  -        if (!getBroker().isInTransaction()) broker.beginTransaction();
  +        if (!getBroker().isInTransaction())
  +        {
  +            if (log.isDebugEnabled()) log.debug("call beginTransaction() on PB instance");
  +            broker.beginTransaction();
  +        }
   
           // Notify objects of impending commits.
           performTransactionAwareBeforeCommit();
   
           // Now perfom the real work
           objectEnvelopeTable.commit();
  -
  -        // Now, we notify everything the commit is done.
  -        performTransactionAwareAfterCommit();
       }
   
       /**
  @@ -349,11 +353,11 @@
        */
       protected synchronized void doClose()
       {
  -        if (!isOpen())
  -        {
  -            throw new IllegalStateException("persist.missingEnd. Tx Status: " +
  -                    TxUtil.getStatusString(getStatus()));
  -        }
  +//        if (!isOpen())
  +//        {
  +//            throw new IllegalStateException("persist.missingEnd. Tx Status: " +
  +//                    TxUtil.getStatusString(getStatus()));
  +//        }
   
           try
           {
  @@ -383,7 +387,7 @@
                   log.debug("Close Transaction and release current PB " + broker + " on tx
" + this);
               // remove current thread from LocalTxManager
               // to avoid problems for succeeding calls of the same thread
  -            txManager.deregisterTx(this);
  +            implementation.getTxManager().deregisterTx(this);
               // now cleanup and prepare for reuse
               refresh();
           }
  @@ -417,7 +421,7 @@
           broker = null;
           registeredForLock.clear();
           unmaterializedLocks.clear();
  -        m_txStatus = Status.STATUS_NO_TRANSACTION;
  +        txStatus = Status.STATUS_NO_TRANSACTION;
       }
   
       /**
  @@ -439,27 +443,16 @@
           }
           catch (Throwable t)
           {
  -            log.error("checkpoint call failed, do abort transaction", t);
  -            try
  -            {
  -                doAbort();
  -            }
  -            finally
  -            {
  -                doClose();
  -                m_txStatus = Status.STATUS_ROLLEDBACK;
  -            }
  -            if (t instanceof TransactionAbortedException)
  -            {
  -                throw (TransactionAbortedException) t;
  -            }
  -            if (t instanceof LockNotGrantedException)
  +            log.error("Checkpoint call failed, do abort transaction", t);
  +            txStatus = Status.STATUS_MARKED_ROLLBACK;
  +            abort();
  +            if(!(t instanceof ODMGRuntimeException))
               {
  -                throw (LockNotGrantedException) t;
  +                throw new TransactionAbortedExceptionOJB("Can't tx.checkpoint() objects:
" + t.getMessage(), t);
               }
               else
               {
  -                throw new TransactionAbortedExceptionOJB(t);
  +                throw (ODMGRuntimeException) t;
               }
           }
       }
  @@ -469,7 +462,11 @@
        */
       public void flush()
       {
  -        if (log.isDebugEnabled()) log.debug("Flush was called - write to database, do not
commit, hold locks on tx " + this);
  +        if (log.isDebugEnabled())
  +        {
  +            log.debug("Flush was called - write changes to database, do not commit, hold
locks on tx " + this);
  +        }
  +
           try
           {
               checkOpen();
  @@ -478,26 +475,15 @@
           catch (Throwable t)
           {
               log.error("flush failed", t);
  -            try
  -            {
  -                doAbort();
  -            }
  -            finally
  -            {
  -                doClose();
  -                m_txStatus = Status.STATUS_ROLLEDBACK;
  -            }
  -            if (t instanceof TransactionAbortedException)
  -            {
  -                throw (TransactionAbortedException) t;
  -            }
  -            if (t instanceof LockNotGrantedException)
  +            txStatus = Status.STATUS_MARKED_ROLLBACK;
  +            abort();
  +            if(!(t instanceof ODMGRuntimeException))
               {
  -                throw (LockNotGrantedException) t;
  +                throw new TransactionAbortedExceptionOJB("Can't tx.flush() objects: " +
t.getMessage(), t);
               }
               else
               {
  -                throw new TransactionAbortedExceptionOJB(t);
  +                throw (ODMGRuntimeException) t;
               }
           }
       }
  @@ -579,70 +565,78 @@
           try
           {
               prepare();
  -            // Never commit transaction that has been marked for rollback
  -            if (m_txStatus == Status.STATUS_MARKED_ROLLBACK)
  -                throw new TransactionAbortedExceptionOJB("persist.markedRollback");
  -            if (m_txStatus != Status.STATUS_PREPARED)
  -                throw new IllegalStateException("persist.missingPrepare");
  +            checkForCommit();
   
  -            m_txStatus = Status.STATUS_COMMITTING;
  -            if (log.isDebugEnabled()) log.debug("Commit transaction " + this + ", commit
on broker " + broker);
  +            txStatus = Status.STATUS_COMMITTING;
  +            if (log.isDebugEnabled()) log.debug("Commit transaction " + this);
  +            // now do real commit on broker
               if(hasBroker()) getBroker().commitTransaction();
  +
  +            // Now, we notify everything the commit is done.
  +            performTransactionAwareAfterCommit();
  +
               doClose();
  -            m_txStatus = Status.STATUS_COMMITTED;
  +            txStatus = Status.STATUS_COMMITTED;
           }
  -        catch (ODMGRuntimeException ex)
  +        catch(Exception ex)
           {
  -            m_txStatus = Status.STATUS_MARKED_ROLLBACK;
  -            if (log.isDebugEnabled()) log.debug("Commit fails, do abort this tx", ex);
  +            log.error("Error while commit objects, do abort tx " + this + ", " + ex.getMessage(),
ex);
  +            txStatus = Status.STATUS_MARKED_ROLLBACK;
               abort();
  -            throw ex;
  +            if(!(ex instanceof ODMGRuntimeException))
  +            {
  +                throw new TransactionAbortedExceptionOJB("Can't commit objects: " + ex.getMessage(),
ex);
  +            }
  +            else
  +            {
  +                throw (ODMGRuntimeException) ex;
  +            }
           }
       }
   
  +    protected void checkForCommit()
  +    {
  +        // Never commit transaction that has been marked for rollback
  +        if (txStatus == Status.STATUS_MARKED_ROLLBACK)
  +            throw new TransactionAbortedExceptionOJB("Illegal tx-status: tx is already
markedRollback");
  +        // Don't commit if not prepared
  +        if (txStatus != Status.STATUS_PREPARED)
  +            throw new IllegalStateException("Illegal tx-status: Do prepare commit before
commit");
  +    }
  +
       /**
        * Prepare does the actual work of moving the changes at the object level
        * into storage (the underlying rdbms for instance). prepare Can be called multiple
times, and
        * does not release locks.
  -     * @return True if the transaction can commit, false if the
  -     * transaction is read only.
  +     *
        * @throws TransactionAbortedException if the transaction has been aborted
        * for any reason.
        * @throws  IllegalStateException Method called if transaction is
        *  not in the proper state to perform this operation
        * @throws TransactionNotInProgressException if the transaction is closed.
        */
  -    protected boolean prepare() throws TransactionAbortedException, LockNotGrantedException
  +    protected void prepare() throws TransactionAbortedException, LockNotGrantedException
       {
  -        if (m_txStatus == Status.STATUS_MARKED_ROLLBACK)
  -            throw new TransactionAbortedExceptionOJB("persist.markedRollback");
  -        if (m_txStatus != Status.STATUS_ACTIVE)
  -            throw new IllegalStateException("persist.noTransaction");
  -        try
  +        if (txStatus == Status.STATUS_MARKED_ROLLBACK)
           {
  -            m_txStatus = Status.STATUS_PREPARING;
  -            doWriteObjects();
  -            m_txStatus = Status.STATUS_PREPARED;
  +            throw new TransactionAbortedExceptionOJB("Prepare Transaction: tx already marked
for rollback");
           }
  -        catch (LockNotGrantedException e)
  +        if (txStatus != Status.STATUS_ACTIVE)
           {
  -            log.error("Could not prepare for commit: " + e.getMessage());
  -            m_txStatus = Status.STATUS_MARKED_ROLLBACK;
  -            throw e;
  +            throw new IllegalStateException("Prepare Transaction: tx status is not 'active',
status is " + TxUtil.getStatusString(txStatus));
           }
  -        catch (TransactionAbortedException e)
  +        try
           {
  -            log.error("Could not prepare for commit: " + e.getMessage());
  -            m_txStatus = Status.STATUS_MARKED_ROLLBACK;
  -            throw e;
  +            txStatus = Status.STATUS_PREPARING;
  +            doWriteObjects();
  +            txStatus = Status.STATUS_PREPARED;
           }
  -        catch (PersistenceBrokerSQLException pbse)
  +        catch (RuntimeException e)
           {
  -            log.error("Could not prepare for commit: " + pbse.getMessage());
  -            m_txStatus = Status.STATUS_MARKED_ROLLBACK;
  -            throw pbse;
  +            log.error("Could not prepare for commit: " + e.getMessage());
  +            txStatus = Status.STATUS_MARKED_ROLLBACK;
  +            throw e;
           }
  -        return true;
       }
   
       /**
  @@ -655,26 +649,60 @@
           /*
           do nothing if already rolledback
           */
  -        if (m_txStatus == Status.STATUS_ROLLEDBACK)
  +        if (txStatus == Status.STATUS_NO_TRANSACTION
  +                || txStatus == Status.STATUS_UNKNOWN
  +                || txStatus == Status.STATUS_ROLLEDBACK)
           {
  +            log.info("Nothing to abort, tx is not active - status is " + TxUtil.getStatusString(txStatus));
               return;
           }
  -        if (m_txStatus != Status.STATUS_ACTIVE && m_txStatus != Status.STATUS_PREPARED
&&
  -                m_txStatus != Status.STATUS_MARKED_ROLLBACK)
  -            throw new IllegalStateException("Illegal state for abort call, state was '"
+ TxUtil.getStatusString(m_txStatus) + "'");
  -        log.info("Abort transaction was called on tx " + this + ", associated PB was "
+ broker);
  +        // check status of tx
  +        if (txStatus != Status.STATUS_ACTIVE && txStatus != Status.STATUS_PREPARED
&&
  +                txStatus != Status.STATUS_MARKED_ROLLBACK)
  +        {
  +            if(txStatus == Status.STATUS_NO_TRANSACTION)
  +            {
  +                throw new TransactionNotInProgressException("The Transaction was not started,
tx " + this);
  +            }
  +            else
  +            {
  +                throw new IllegalStateException("Illegal state for abort call, state was
'" + TxUtil.getStatusString(txStatus) + "'");
  +            }
  +        }
  +        if(log.isEnabledFor(Logger.INFO))
  +        {
  +            log.info("Abort transaction was called on tx " + this);
  +        }
           try
           {
  -            doAbort();
  -            if(hasBroker() && getBroker().isInTransaction())
  +            try
  +            {
  +                doAbort();
  +            }
  +            catch(Exception e)
               {
  -                getBroker().abortTransaction();
  +                log.error("Error while abort transaction, will be skipped", e);
  +            }
  +
  +            // used in managed environments, ignored in non-managed
  +            this.implementation.getTxManager().abortExternalTx(this);
  +
  +            try
  +            {
  +                if(hasBroker() && getBroker().isInTransaction())
  +                {
  +                    getBroker().abortTransaction();
  +                }
  +            }
  +            catch(Exception e)
  +            {
  +                log.error("Error while do abort used broker instance, will be skipped",
e);
               }
           }
           finally
           {
  +            txStatus = Status.STATUS_ROLLEDBACK;
               doClose();
  -            m_txStatus = Status.STATUS_ROLLEDBACK;
           }
       }
   
  @@ -690,6 +718,20 @@
        */
       public synchronized void begin()
       {
  +        checkForBegin();
  +        if (log.isDebugEnabled()) log.debug("Begin transaction was called on tx " + this);
  +        // initialize the ObjectEnvelope table
  +        objectEnvelopeTable = new ObjectEnvelopeTable(this);
  +        // initialize the temporary hashtable
  +        myNrm = new Hashtable();
  +        // register transaction
  +        implementation.getTxManager().registerTx(this);
  +        // mark tx as active (open)
  +        txStatus = Status.STATUS_ACTIVE;
  +    }
  +
  +    protected void checkForBegin()
  +    {
           /**
            * Is the associated database non-null and open? ODMG 3.0 says it must be.
            */
  @@ -702,15 +744,6 @@
               log.error("Transaction is already open");
               throw new org.odmg.TransactionInProgressException("Impossible to call begin
on already opened tx");
           }
  -        // initialize the ObjectEnvelope table
  -        objectEnvelopeTable = new ObjectEnvelopeTable(this);
  -        // initialize the temporary hashtable
  -        myNrm = new Hashtable();
  -        // register transaction
  -        txManager.registerTx(this);
  -        // mark tx as active (open)
  -        m_txStatus = Status.STATUS_ACTIVE;
  -        if (log.isDebugEnabled()) log.debug("Begin transaction was called on tx " + this
+ ", with associated PB " + broker);
       }
   
       public String getGUID()
  @@ -830,7 +863,7 @@
           {
               assLockMode = Transaction.READ;
           }
  -        if (useImplicitLocking)
  +        if (implicitLocking)
           {
               lockReferences(cld, objectToRegister, assLockMode);
           }
  @@ -844,7 +877,7 @@
           {
               assLockMode = Transaction.READ;
           }
  -        if (useImplicitLocking)
  +        if (implicitLocking)
           {
               Iterator i = cld.getCollectionDescriptors().iterator();
               while (i.hasNext())
  @@ -1120,7 +1153,7 @@
           OdmgConfiguration odmgConfig = (OdmgConfiguration) config;
   
           useWriteLocks = odmgConfig.lockAssociationAsWrites();
  -        useImplicitLocking = odmgConfig.useImplicitLocking();
  +        implicitLocking = odmgConfig.useImplicitLocking();
       }
   
       /**
  @@ -1128,7 +1161,7 @@
        */
       public synchronized void setImplicitLocking(boolean value)
       {
  -        useImplicitLocking = value;
  +        implicitLocking = value;
       }
   
       /**
  @@ -1155,7 +1188,7 @@
           for (Iterator iterator = data.iterator(); iterator.hasNext();)
           {
               Object o = iterator.next();
  -            if (useImplicitLocking && this.isOpen())
  +            if (implicitLocking && this.isOpen())
               {
                   int lock = useWriteLocks ? Transaction.WRITE : Transaction.READ;
                   this.register(null, o, lock, false);
  @@ -1165,18 +1198,26 @@
   
       protected void performTransactionAwareBeforeCommit()
       {
  -        Enumeration en = objectEnvelopeTable.elements();
  -        while (en.hasMoreElements())
  +        Enumeration enum = objectEnvelopeTable.elements();
  +        while (enum.hasMoreElements())
           {
  -            ((ObjectEnvelope) en.nextElement()).beforeCommit();
  +            ((ObjectEnvelope) enum.nextElement()).beforeCommit();
           }
       }
       protected void performTransactionAwareAfterCommit()
       {
           Enumeration en = objectEnvelopeTable.elements();
  -        while (en.hasMoreElements())
  +        try
           {
  -            ((ObjectEnvelope) en.nextElement()).afterCommit();
  +            while (en.hasMoreElements())
  +            {
  +                ((ObjectEnvelope) en.nextElement()).afterCommit();
  +            }
  +        }
  +        catch(Exception e)
  +        {
  +            log.error("Unexpected error while perform 'TransactionAware#afterCommit()'
listener after commit of objects," +
  +                    " after commit you can't rollback - exception will be skipped.", e);
           }
       }
       protected void performTransactionAwareBeforeRollback()
  @@ -1190,16 +1231,25 @@
               }
               catch(Exception e)
               {
  -                log.error("TransactionAware#beforeRollback call cause exception, will be
ignored to complete rollback", e);
  +                log.error("Unexpected error while perform 'TransactionAware#beforeAbort()'
listener before rollback of objects" +
  +                    " - exception will be skipped to complete rollback.", e);
               }
           }
       }
       protected void performTransactionAwareAfterRollback()
       {
           Enumeration en = objectEnvelopeTable.elements();
  -        while (en.hasMoreElements())
  +        try
  +        {
  +            while (en.hasMoreElements())
  +            {
  +                ((ObjectEnvelope) en.nextElement()).afterAbort();
  +            }
  +        }
  +        catch(Exception e)
           {
  -            ((ObjectEnvelope) en.nextElement()).afterAbort();
  +            log.error("Unexpected error while perform 'TransactionAware#afterAbort()' listener
after rollback of objects" +
  +                    " - exception will be skipped.", e);
           }
       }
   }
  
  
  

---------------------------------------------------------------------
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