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/06/09 03:25:23 UTC

cvs commit: db-ojb/src/java/org/apache/ojb/broker/core PersistenceBrokerFactorySyncImpl.java

arminw      2004/06/08 18:25:23

  Modified:    src/java/org/apache/ojb/broker/core
                        PersistenceBrokerFactorySyncImpl.java
  Log:
  when a jta-tx is running associate the PB instance with tx and
  return the same PB instance for all further calls to PBF
  
  Revision  Changes    Path
  1.6       +117 -24   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.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- PersistenceBrokerFactorySyncImpl.java	3 May 2004 23:06:55 -0000	1.5
  +++ PersistenceBrokerFactorySyncImpl.java	9 Jun 2004 01:25:23 -0000	1.6
  @@ -1,5 +1,20 @@
   package org.apache.ojb.broker.core;
   
  +/* Copyright 2004-2004 The Apache Software Foundation
  + *
  + * Licensed under the Apache License, Version 2.0 (the "License");
  + * you may not use this file except in compliance with the License.
  + * You may obtain a copy of the License at
  + *
  + *     http://www.apache.org/licenses/LICENSE-2.0
  + *
  + * Unless required by applicable law or agreed to in writing, software
  + * distributed under the License is distributed on an "AS IS" BASIS,
  + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  + * See the License for the specific language governing permissions and
  + * limitations under the License.
  + */
  +
   import javax.transaction.RollbackException;
   import javax.transaction.Status;
   import javax.transaction.Synchronization;
  @@ -7,38 +22,42 @@
   import javax.transaction.Transaction;
   import javax.transaction.TransactionManager;
   import java.lang.reflect.Field;
  -import java.util.ArrayList;
   import java.util.Collections;
  +import java.util.HashMap;
   import java.util.Iterator;
  -import java.util.List;
   import java.util.Map;
   import java.util.WeakHashMap;
   
   import org.apache.commons.pool.KeyedObjectPool;
   import org.apache.ojb.broker.PBFactoryException;
  +import org.apache.ojb.broker.PBKey;
   import org.apache.ojb.broker.PersistenceBroker;
   import org.apache.ojb.broker.TransactionAbortedException;
   import org.apache.ojb.broker.TransactionInProgressException;
   import org.apache.ojb.broker.TransactionNotInProgressException;
   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.apache.ojb.broker.transaction.tm.TransactionManagerFactoryException;
   import org.apache.ojb.broker.transaction.tm.TransactionManagerFactoryFactory;
  +import org.apache.ojb.broker.util.BrokerHelper;
  +import org.apache.ojb.broker.util.logging.Logger;
  +import org.apache.ojb.broker.util.logging.LoggerFactory;
   
  -/* Copyright 2004-2004 The Apache Software Foundation
  - *
  - * Licensed under the Apache License, Version 2.0 (the "License");
  - * you may not use this file except in compliance with the License.
  - * You may obtain a copy of the License at
  - *
  - *     http://www.apache.org/licenses/LICENSE-2.0
  +/**
  + * Workaround for participate the PB-api in JTA {@link javax.transaction.Transaction transaction} by
  + * implementing the {@link javax.transaction.Synchronization} interface.
  + * <br/>
  + * This may will be deprecated when we implemented a full JCA compliant connector.
  + * <br/>
  + * When a new {@link org.apache.ojb.broker.PersistenceBroker} instance is created in method
  + * {@link #wrapBrokerWithPoolingHandle}
  + * the given PB instance is wrapped with {@link PersistenceBrokerSyncImpl} before it was put to the PB-pool.
  + * When a PB instance was requested class try to lookup the current JTA transaction in
  + * {@link #wrapRequestedBrokerInstance} before the pooled PB instance was wrapped with the PB handle.
  + * If a running tx was found the PB instance was registered with the transaction using the
  + * {@link Synchronization} interface.
    *
  - * Unless required by applicable law or agreed to in writing, software
  - * distributed under the License is distributed on an "AS IS" BASIS,
  - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  - * See the License for the specific language governing permissions and
  - * limitations under the License.
  + * @author <a href="mailto:armin@codeAuLait.de">Armin Waibel</a>
  + * @version $Id$
    */
   public class PersistenceBrokerFactorySyncImpl extends PersistenceBrokerFactoryDefaultImpl
   {
  @@ -60,6 +79,50 @@
           txRegistry = new TxRegistry();
       }
   
  +    public PersistenceBroker createPersistenceBroker(PBKey pbKey) throws PBFactoryException
  +    {
  +        PersistenceBroker result = null;
  +        /*
  +        try to find a valid PBKey, if given key does not full match
  +        */
  +        pbKey = BrokerHelper.crossCheckPBKey(pbKey);
  +        /*
  +        arminw:
  +        First try to find a running JTA-tx. If a tx was found we try to find
  +        an associated PB instance. This ensures that in a running tx
  +        always the same PB instance was used.
  +        If no tx was found we lookup a instance from pool.
  +        All used PB instances always be wrapped with a "PBHandle"
  +        */
  +        Transaction tx = null;
  +        try
  +        {
  +            // search for an active tx
  +            tx = searchForValidTx();
  +        }
  +        catch (SystemException e)
  +        {
  +            throw new PBFactoryException("Can't create PB instance, failure while lookup" +
  +                    " running JTA transaction",e);
  +        }
  +        if (tx != null)
  +        {
  +            result = txRegistry.findBroker(tx, pbKey);
  +        }
  +
  +        if(result == null || result.isClosed())
  +        {
  +            // lookup new PB instance
  +            result = super.createPersistenceBroker(pbKey);
  +        }
  +        else
  +        {
  +            // wrap with PB handle
  +            super.wrapRequestedBrokerInstance(result);
  +        }
  +        return result;
  +    }
  +
       protected PersistenceBroker wrapBrokerWithPoolingHandle(PersistenceBroker broker, KeyedObjectPool pool)
       {
           // wrap real PB instance with an extended version of pooling PB
  @@ -291,28 +354,35 @@
        */
       class TransactionBox implements Synchronization
       {
  -        List syncList = new ArrayList();
  +        Transaction jtaTx;
  +        Map syncMap = new HashMap();
           boolean isLocked = false;
           boolean isClosed = false;
   
  -        public TransactionBox()
  +        public TransactionBox(Transaction tx)
  +        {
  +            this.jtaTx = tx;
  +        }
  +
  +        PersistenceBroker find(PBKey key)
           {
  +            return (PersistenceBroker) syncMap.get(key);
           }
   
  -        void add(Synchronization syncObj)
  +        void add(PersistenceBroker syncObj)
           {
               if (isLocked)
               {
                   throw new PBFactoryException("Can't associate object with JTA transaction, because tx-completion started");
               }
  -            syncList.add(syncObj);
  +            syncMap.put(syncObj.getPBKey(), (Synchronization) syncObj);
           }
   
           public void afterCompletion(int status)
           {
               boolean failures = false;
               Synchronization synchronization = null;
  -            for (Iterator iterator = syncList.iterator(); iterator.hasNext();)
  +            for (Iterator iterator = syncMap.values().iterator(); iterator.hasNext();)
               {
                   try
                   {
  @@ -327,6 +397,8 @@
                   }
               }
               isClosed = true;
  +            // discard association of PB instances and jta-tx
  +            txRegistry.removeTxBox(jtaTx);
               if (failures)
               {
                   throw new PBFactoryException("Unexpected error occured while performing" +
  @@ -338,7 +410,7 @@
           {
               boolean failures = false;
               Synchronization synchronization = null;
  -            for (Iterator iterator = syncList.iterator(); iterator.hasNext();)
  +            for (Iterator iterator = syncMap.values().iterator(); iterator.hasNext();)
               {
                   try
                   {
  @@ -380,18 +452,39 @@
               txBoxMap = Collections.synchronizedMap(new WeakHashMap());
           }
   
  -        void register(Transaction tx, Synchronization syncObject) throws RollbackException, SystemException
  +        void register(Transaction tx, PersistenceBroker syncObject) throws RollbackException, SystemException
           {
               TransactionBox txBox = (TransactionBox) txBoxMap.get(tx);
               if (txBox == null || txBox.isClosed)
               {
                   // if environment reuse tx instances we can find closed TransactionBox instances
                   if (txBox != null) txBoxMap.remove(tx);
  -                txBox = new TransactionBox();
  +                txBox = new TransactionBox(tx);
                   tx.registerSynchronization(txBox);
                   txBoxMap.put(tx, txBox);
               }
               txBox.add(syncObject);
  +        }
  +
  +        PersistenceBroker findBroker(Transaction tx, PBKey pbKey)
  +        {
  +            PersistenceBroker result = null;
  +            TransactionBox txBox = (TransactionBox) txBoxMap.get(tx);
  +            if(txBox != null)
  +            {
  +                result = txBox.find(pbKey);
  +            }
  +            return result;
  +        }
  +
  +        TransactionBox findTxBox(Transaction tx)
  +        {
  +            return (TransactionBox) txBoxMap.get(tx);
  +        }
  +
  +        void removeTxBox(Transaction tx)
  +        {
  +            txBoxMap.remove(tx);
           }
       }
   }
  
  
  

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