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