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