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 ar...@apache.org on 2004/11/28 04:16:38 UTC

cvs commit: db-ojb/src/java/org/apache/ojb/broker KeyConstraintViolatedException.java OJB.java PersistenceBrokerFactory.java

arminw      2004/11/27 19:16:38

  Modified:    src/java/org/apache/ojb/broker/core
                        PersistenceBrokerFactorySyncImpl.java
                        PersistenceBrokerHandle.java
               src/java/org/apache/ojb/broker/util/pooling
                        ByPassConnection.java
               src/java/org/apache/ojb/broker
                        KeyConstraintViolatedException.java OJB.java
                        PersistenceBrokerFactory.java
  Log:
  fix problems of abandoned connection and statements in managed environments
  + minor changes
  
  Revision  Changes    Path
  1.11      +131 -36   db-ojb/src/java/org/apache/ojb/broker/core/PersistenceBrokerFactorySyncImpl.java
  
  Index: PersistenceBrokerFactorySyncImpl.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/core/PersistenceBrokerFactorySyncImpl.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- PersistenceBrokerFactorySyncImpl.java	14 Nov 2004 09:34:27 -0000	1.10
  +++ PersistenceBrokerFactorySyncImpl.java	28 Nov 2004 03:16:38 -0000	1.11
  @@ -27,6 +27,8 @@
   import java.util.Iterator;
   import java.util.Map;
   import java.util.WeakHashMap;
  +import java.util.List;
  +import java.util.ArrayList;
   
   import org.apache.commons.pool.ObjectPool;
   import org.apache.ojb.broker.PBFactoryException;
  @@ -82,7 +84,6 @@
   
       public PersistenceBroker createPersistenceBroker() throws PBFactoryException
       {
  -        PersistenceBroker result = null;
           /*
           arminw:
           First try to find a running JTA-tx. If a tx was found we try to find
  @@ -102,6 +103,7 @@
               throw new PBFactoryException("Can't create PB instance, failure while lookup" +
                       " running JTA transaction",e);
           }
  +        PersistenceBrokerSyncImpl result = null;
           if (tx != null)
           {
               result = txRegistry.findBroker(tx, getConfiguration().getKey());
  @@ -109,15 +111,17 @@
   
           if(result == null || result.isClosed())
           {
  -            // lookup new PB instance
  -            result = super.createPersistenceBroker();
  +            // we have to lookup new PB instance with wrapped with handle
  +            // method #wrapRequestedBrokerInstance wraps the new instance
  +            // with a handle
  +            return super.createPersistenceBroker();
           }
           else
           {
  -            // wrap with PB handle
  -            result = super.wrapRequestedBrokerInstance(result);
  +            // we found a PB instance that was already in use within the same JTA-tx
  +            // so we only return a new handle
  +            return new PersistenceBrokerSyncHandle(result);
           }
  -        return result;
       }
   
       protected PersistenceBroker wrapBrokerWithPoolingHandle(PersistenceBroker broker, ObjectPool pool)
  @@ -171,7 +175,7 @@
           {
               throw new PBFactoryException("Error while try to participate in JTA transaction", e);
           }
  -        return super.wrapRequestedBrokerInstance(broker);
  +        return new PersistenceBrokerSyncHandle(pb);
       }
   
       private Transaction searchForValidTx() throws SystemException
  @@ -222,6 +226,10 @@
       public static class PersistenceBrokerSyncImpl extends PoolablePersistenceBroker implements Synchronization
       {
           private Logger log = LoggerFactory.getLogger(PersistenceBrokerSyncImpl.class);
  +        /**
  +         * Used to register all handles using this PB instance
  +         */
  +        private List handleList = new ArrayList();
   
           public PersistenceBrokerSyncImpl(PersistenceBroker broker, ObjectPool pool)
           {
  @@ -231,6 +239,17 @@
           public void beforeCompletion()
           {
               if (log.isDebugEnabled()) log.debug("beforeCompletion was called, nothing to do");
  +            if(handleList.size() > 0)
  +            {
  +                for(int i = 0; i < handleList.size(); i++)
  +                {
  +                    log.warn("Found unclosed PersistenceBroker handle, will do automatic close. Please make" +
  +                            " sure that all used PB instances will be closed.");
  +                    PersistenceBrokerHandle pbh = (PersistenceBrokerHandle) handleList.get(i);
  +                    pbh.close();
  +                }
  +                handleList.clear();
  +            }
               ConnectionManagerIF cm = serviceConnectionManager();
               if(cm.isBatchMode()) cm.executeBatch();
               // close connection immediately when in JTA-tx to avoid bad reports from server con-pool
  @@ -256,7 +275,16 @@
               {
                   if (status != Status.STATUS_COMMITTED)
                   {
  -                    log.error("Abort PB-tx, status of JTA tx is " + getStatusFlagAsString(status));
  +                    if (status == Status.STATUS_ROLLEDBACK || status == Status.STATUS_ROLLING_BACK)
  +                    {
  +                        if (log.isDebugEnabled()) log.debug("Aborting PB-tx due to JTA initiated Rollback: "
  +                                + getStatusFlagAsString(status));
  +                    }
  +                    else
  +                    {
  +                        log.error("Aborting PB-tx due to inconsistent, and unexpected, status of JTA tx: "
  +                                + getStatusFlagAsString(status));
  +                    }
                       internAbort();
                   }
                   else
  @@ -303,39 +331,70 @@
                   if we not in JTA-tx, we close PB instance in a "normal" way. The PB.close()
                   should also release the used connection.
                   */
  -                super.close();
  +                doRealClose();
               }
               else
               {
  -                /*
  -                arminw:
  -                if in JTA-tx, we don't really close the underlying PB instance (return PB
  -                instance to pool, release used connection). As recently as the JTA was
  -                completed we can return PB instance to pool. Thus after tx completion method
  -                doRealClose() was called to close (return to pool) underlying PB instance.
  -
  -                But to free used resources as soon as possible, we release the used connection
  -                immediately. The JTA-tx will handle the connection status in a proper way.
  -                */
  -                if (log.isDebugEnabled())
  -                    log.debug("PB close was called, only close the PB handle when in JTA-tx");
  -                ConnectionManagerIF cm = serviceConnectionManager();
  -                if(cm.isInLocalTransaction())
  +                // if we in tx and other handles operate on the same PB instance, do
  +                // nothing, till all handles are closed.
  +                if(handleList.size() > 0)
                   {
  +                    if(log.isEnabledFor(Logger.INFO)) log.info("PB.close(): Active used by " + handleList.size()
  +                            + " handle objects, will skip close call");
  +                }
  +                else
  +                {
  +                    /*
  +                    arminw:
  +                    if in JTA-tx, we don't really close the underlying PB instance (return PB
  +                    instance to pool, release used connection). As recently as the JTA was
  +                    completed we can return PB instance to pool. Thus after tx completion method
  +                    doRealClose() was called to close (return to pool) underlying PB instance.
  +
  +                    But to free used resources as soon as possible, we release the used connection
  +                    immediately. The JTA-tx will handle the connection status in a proper way.
  +                    */
  +                    if (log.isDebugEnabled())
  +                        log.debug("PB close was called, only close the PB handle when in JTA-tx");
  +
                       /*
  +                    TODO: workaround, in 1.1 use special method do handle this stuff
                       arminw:
  -                    in managed environment this call will be ignored because, the JTA transaction
  -                    manager control the connection status. But to make connectionManager happy we
  -                    have to complete the "local tx" of the connectionManager before release the
  -                    connection
  +                    needed to prevent unclosed connection Statement instances when RsIterator
  +                    wasn't fully materialized in managed environment, because RsIterator is
  +                    a PBStateListener and below we close the connection.
                       */
  -                    cm.localCommit();
  +                    PersistenceBrokerImpl pb = ((PersistenceBrokerImpl) getInnermostDelegate());
  +                    pb.fireBrokerEvent(pb.BEFORE_CLOSE_EVENT);
  +
  +                    ConnectionManagerIF cm = serviceConnectionManager();
  +                    if(cm.isInLocalTransaction())
  +                    {
  +                        /*
  +                        arminw:
  +                        in managed environment con.commit calls will be ignored because, the JTA
  +                        transaction manager control the connection status. But to make
  +                        connectionManager happy we have to complete the "local tx" of the
  +                        connectionManager before release the connection
  +                        */
  +                        cm.localCommit();
  +                    }
  +                    cm.releaseConnection();
                   }
  -                cm.releaseConnection();
               }
               return true;
           }
   
  +        void registerHandle(PersistenceBrokerHandle handle)
  +        {
  +            handleList.add(handle);
  +        }
  +
  +        void deregisterHandle(PersistenceBrokerHandle handle)
  +        {
  +            handleList.remove(handle);
  +        }
  +
           public void beginTransaction() throws TransactionInProgressException, TransactionAbortedException
           {
               throw new UnsupportedOperationException("In managed environments only JTA transaction demarcation allowed");
  @@ -370,12 +429,12 @@
               this.jtaTx = tx;
           }
   
  -        PersistenceBroker find(PBKey key)
  +        PersistenceBrokerSyncImpl find(PBKey key)
           {
  -            return (PersistenceBroker) syncMap.get(key);
  +            return (PersistenceBrokerSyncImpl) syncMap.get(key);
           }
   
  -        void add(PersistenceBroker syncObj)
  +        void add(PersistenceBrokerSyncImpl syncObj)
           {
               if (isLocked)
               {
  @@ -458,7 +517,7 @@
               txBoxMap = Collections.synchronizedMap(new WeakHashMap());
           }
   
  -        void register(Transaction tx, PersistenceBroker syncObject) throws RollbackException, SystemException
  +        void register(Transaction tx, PersistenceBrokerSyncImpl syncObject) throws RollbackException, SystemException
           {
               TransactionBox txBox = (TransactionBox) txBoxMap.get(tx);
               if (txBox == null || txBox.isClosed)
  @@ -472,9 +531,9 @@
               txBox.add(syncObject);
           }
   
  -        PersistenceBroker findBroker(Transaction tx, PBKey pbKey)
  +        PersistenceBrokerSyncImpl findBroker(Transaction tx, PBKey pbKey)
           {
  -            PersistenceBroker result = null;
  +            PersistenceBrokerSyncImpl result = null;
               TransactionBox txBox = (TransactionBox) txBoxMap.get(tx);
               if(txBox != null)
               {
  @@ -491,6 +550,42 @@
           void removeTxBox(Transaction tx)
           {
               txBoxMap.remove(tx);
  +        }
  +    }
  +
  +    //****************************************************
  +    // inner class
  +    //****************************************************
  +    /**
  +     * This wrapper was used when a PB instance which was already in use by a
  +     * transaction was found.
  +     */
  +    class PersistenceBrokerSyncHandle extends PersistenceBrokerHandle
  +    {
  +        /**
  +         * Constructor for the handle, set itself in
  +         * {@link PersistenceBrokerThreadMapping#setCurrentPersistenceBroker}
  +         */
  +        public PersistenceBrokerSyncHandle(PersistenceBrokerSyncImpl broker)
  +        {
  +            super(broker);
  +            // we register handle at underlying PB instance
  +            broker.registerHandle(this);
  +        }
  +
  +        public boolean isClosed()
  +        {
  +            return super.isClosed();
  +        }
  +
  +        public boolean close()
  +        {
  +            if(getDelegate() != null)
  +            {
  +                // deregister from underlying PB instance
  +                ((PersistenceBrokerSyncImpl) getDelegate()).deregisterHandle(this);
  +            }
  +            return super.close();
           }
       }
   }
  
  
  
  1.11      +2 -2      db-ojb/src/java/org/apache/ojb/broker/core/PersistenceBrokerHandle.java
  
  Index: PersistenceBrokerHandle.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/core/PersistenceBrokerHandle.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- PersistenceBrokerHandle.java	4 Apr 2004 23:53:33 -0000	1.10
  +++ PersistenceBrokerHandle.java	28 Nov 2004 03:16:38 -0000	1.11
  @@ -17,13 +17,13 @@
    * See the License for the specific language governing permissions and
    * limitations under the License.
    */
  -public final class PersistenceBrokerHandle extends DelegatingPersistenceBroker
  +public class PersistenceBrokerHandle extends DelegatingPersistenceBroker
   {
       /**
        * Constructor for the handle, set itself in
        * {@link PersistenceBrokerThreadMapping#setCurrentPersistenceBroker}
        */
  -    public PersistenceBrokerHandle(PersistenceBroker broker)
  +    public PersistenceBrokerHandle(final PersistenceBroker broker)
       {
           super(broker);
           PersistenceBrokerThreadMapping.setCurrentPersistenceBroker(broker.getPBKey(), this);
  
  
  
  1.11      +0 -8      db-ojb/src/java/org/apache/ojb/broker/util/pooling/ByPassConnection.java
  
  Index: ByPassConnection.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/util/pooling/ByPassConnection.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- ByPassConnection.java	8 Sep 2004 22:14:50 -0000	1.10
  +++ ByPassConnection.java	28 Nov 2004 03:16:38 -0000	1.11
  @@ -64,14 +64,6 @@
       }
   
       /**
  -     * close the wrapped connection
  -     */
  -    public void close() throws SQLException
  -    {
  -        super.close();
  -    }
  -
  -    /**
        * no-op
        */
       public void rollback() throws SQLException
  
  
  
  1.6       +11 -27    db-ojb/src/java/org/apache/ojb/broker/KeyConstraintViolatedException.java
  
  Index: KeyConstraintViolatedException.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/KeyConstraintViolatedException.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- KeyConstraintViolatedException.java	4 Apr 2004 23:53:30 -0000	1.5
  +++ KeyConstraintViolatedException.java	28 Nov 2004 03:16:38 -0000	1.6
  @@ -1,5 +1,7 @@
   package org.apache.ojb.broker;
   
  +import java.sql.SQLException;
  +
   /* Copyright 2002-2004 The Apache Software Foundation
    *
    * Licensed under the Apache License, Version 2.0 (the "License");
  @@ -16,48 +18,30 @@
    */
   
   /**
  - * Base class of all exceptions used in OJB.
  + * Exception indicate an SQL key contraint violation.
    *
    * @author <a href="mailto:mattbaird@yahoo.com">Matthew Baird<a>
    * @version $Id$
    */
   
  -public class KeyConstraintViolatedException
  -        extends PersistenceBrokerException
  +public class KeyConstraintViolatedException extends PersistenceBrokerSQLException
   {
  -    /**
  -     * Constructor for KeyConstraintViolatedException.
  -     */
       public KeyConstraintViolatedException()
       {
  -        super();
       }
   
  -    /**
  -     * Constructor for KeyConstraintViolatedException.
  -     * @param message
  -     */
  -    public KeyConstraintViolatedException(String message)
  +    public KeyConstraintViolatedException(SQLException t)
       {
  -        super(message);
  +        super(t);
       }
   
  -    /**
  -     * Constructor for KeyConstraintViolatedException.
  -     * @param message
  -     * @param cause
  -     */
  -    public KeyConstraintViolatedException(String message, Throwable cause)
  +    public KeyConstraintViolatedException(String message)
       {
  -        super(message, cause);
  +        super(message);
       }
   
  -    /**
  -     * Constructor for KeyConstraintViolatedException.
  -     * @param cause
  -     */
  -    public KeyConstraintViolatedException(Throwable cause)
  +    public KeyConstraintViolatedException(String message, SQLException t)
       {
  -        super(cause);
  +        super(message, t);
       }
   }
  
  
  
  1.5       +7 -8      db-ojb/src/java/org/apache/ojb/broker/OJB.java
  
  Index: OJB.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/OJB.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- OJB.java	14 Nov 2004 09:33:37 -0000	1.4
  +++ OJB.java	28 Nov 2004 03:16:38 -0000	1.5
  @@ -49,12 +49,11 @@
   {
       /** Default filename of the OJB properties file */
       public static final String DEFAULT_PROPERTIES_FILE = "OJB.properties";
  -
  -    private Logger log = LoggerFactory.getLogger(OJB.class);
  -
       public static final ObjectModification INSERT = ObjectModificationImpl.INSERT;
       public static final ObjectModification UPDATE = ObjectModificationImpl.UPDATE;
   
  +    private Logger log = LoggerFactory.getLogger(OJB.class);
  +
       /** The container */
       private ComponentContainer container;
       /** Whether this runtime is fully initialized */
  @@ -259,7 +258,7 @@
           /*
           We have to differentiate three cases:
           1. one model, many different DB --> One CacheManager per DB
  -        2. one model, many JCD fro same DB (e.g. different DB roles) --> CacheManager have to shared
  +        2. one model, many JCD for the same DB (e.g. different DB roles) --> CacheManager have to shared
           3. many models for the same JCD --> Different CacheManager for each model, but invalidation
              of cached objects one another (CacheManager#registerForObjectInvalidation)
           */
  @@ -400,10 +399,10 @@
           }
       }
   
  -    public static final class ObjectModificationImpl implements ObjectModification
  +    static final class ObjectModificationImpl implements ObjectModification
       {
  -        public static final ObjectModification INSERT = new ObjectModificationImpl(true, false);
  -        public static final ObjectModification UPDATE = new ObjectModificationImpl(false, true);
  +        static final ObjectModification INSERT = new ObjectModificationImpl(true, false);
  +        static final ObjectModification UPDATE = new ObjectModificationImpl(false, true);
   
           private boolean needsInsert;
           private boolean needsUpdate;
  
  
  
  1.28      +3 -4      db-ojb/src/java/org/apache/ojb/broker/PersistenceBrokerFactory.java
  
  Index: PersistenceBrokerFactory.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/PersistenceBrokerFactory.java,v
  retrieving revision 1.27
  retrieving revision 1.28
  diff -u -r1.27 -r1.28
  --- PersistenceBrokerFactory.java	14 Nov 2004 09:33:37 -0000	1.27
  +++ PersistenceBrokerFactory.java	28 Nov 2004 03:16:38 -0000	1.28
  @@ -23,7 +23,6 @@
    * this class with {@link OJB}.
    *
    * @see OJB
  - * @see org.apache.ojb.broker.core.PersistenceBrokerFactoryFactory
    * @see org.apache.ojb.broker.core.PersistenceBrokerFactoryIF
    *
    * @author Thomas Mahler
  @@ -50,7 +49,7 @@
       }
   
       /**
  -     * @see MetadataManager#setDefaultPBKey(org.apache.ojb.broker.PBKey)
  +     * @see org.apache.ojb.broker.metadata.MetadataManager#setDefaultPBKey(org.apache.ojb.broker.PBKey)
        */
       public static void setDefaultKey(PBKey key)
       {
  @@ -58,7 +57,7 @@
       }
   
       /**
  -     * @see MetadataManager#getDefaultPBKey()
  +     * @see org.apache.ojb.broker.metadata.MetadataManager#getDefaultPBKey()
        */
       public static PBKey getDefaultKey()
       {
  
  
  

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