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 00:46:32 UTC
cvs commit: db-ojb/src/java/org/apache/ojb/broker KeyConstraintViolatedException.java
arminw 2004/11/27 15:46:32
Modified: src/java/org/apache/ojb/broker/core Tag: OJB_1_0_RELEASE
PersistenceBrokerFactorySyncImpl.java
PersistenceBrokerHandle.java
src/java/org/apache/ojb/broker/util/pooling Tag:
OJB_1_0_RELEASE ByPassConnection.java
src/java/org/apache/ojb/broker Tag: OJB_1_0_RELEASE
KeyConstraintViolatedException.java
Log:
improve exception/tx status handling
fix problems with abbandoned connections in managed environments
Revision Changes Path
No revision
No revision
1.7.2.2 +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.7.2.1
retrieving revision 1.7.2.2
diff -u -r1.7.2.1 -r1.7.2.2
--- PersistenceBrokerFactorySyncImpl.java 27 Jul 2004 00:33:11 -0000 1.7.2.1
+++ PersistenceBrokerFactorySyncImpl.java 27 Nov 2004 23:46:32 -0000 1.7.2.2
@@ -22,9 +22,11 @@
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;
@@ -81,7 +83,6 @@
public PersistenceBroker createPersistenceBroker(PBKey pbKey) throws PBFactoryException
{
- PersistenceBroker result = null;
/*
try to find a valid PBKey, if given key does not full match
*/
@@ -105,6 +106,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, pbKey);
@@ -112,15 +114,17 @@
if(result == null || result.isClosed())
{
- // lookup new PB instance
- result = super.createPersistenceBroker(pbKey);
+ // we have to lookup new PB instance with wrapped with handle
+ // method #wrapRequestedBrokerInstance wraps the new instance
+ // with a handle
+ return super.createPersistenceBroker(pbKey);
}
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, KeyedObjectPool pool)
@@ -174,7 +178,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
@@ -225,6 +229,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, KeyedObjectPool pool)
{
@@ -234,6 +242,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
@@ -259,7 +278,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
@@ -306,39 +334,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");
@@ -373,12 +432,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)
{
@@ -461,7 +520,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)
@@ -475,9 +534,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)
{
@@ -494,6 +553,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.10.2.1 +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.10.2.1
diff -u -r1.10 -r1.10.2.1
--- PersistenceBrokerHandle.java 4 Apr 2004 23:53:33 -0000 1.10
+++ PersistenceBrokerHandle.java 27 Nov 2004 23:46:32 -0000 1.10.2.1
@@ -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);
No revision
No revision
1.9.2.2 +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.9.2.1
retrieving revision 1.9.2.2
diff -u -r1.9.2.1 -r1.9.2.2
--- ByPassConnection.java 8 Sep 2004 22:13:00 -0000 1.9.2.1
+++ ByPassConnection.java 27 Nov 2004 23:46:32 -0000 1.9.2.2
@@ -64,14 +64,6 @@
}
/**
- * close the wrapped connection
- */
- public void close() throws SQLException
- {
- super.close();
- }
-
- /**
* no-op
*/
public void rollback() throws SQLException
No revision
No revision
1.5.2.1 +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.5.2.1
diff -u -r1.5 -r1.5.2.1
--- KeyConstraintViolatedException.java 4 Apr 2004 23:53:30 -0000 1.5
+++ KeyConstraintViolatedException.java 27 Nov 2004 23:46:32 -0000 1.5.2.1
@@ -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);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org