1. I see the problem with the old xa wrapper.
2. I will look at this further later.
3. I think your proposal will break the local tx behavior (maybe I didn't
look far enough, I have to run)
4. Won't the new xa wrapper in jboss 4 also solve the problem by always
using the same Connection from the XAConnection, just handing out wrappers
to it?
thanks
david jencks
On 2002.11.01 11:29:09 -0500 Igor Fedorenko wrote:
> Ok, here is the same example with some more details/comments. There was
> a mistake in my original explanation and I apoligize for confusion.
>
> BeanA allocates a connection
> - TxConnectionManager.getManagedConnection allocates
> new managed connection mc1 of type
> org.jboss.resource.adapter.jdbc.xa.XAManagedConnection which
> is a wrapper for (oracle) xa connection xaconn1.
> - TxConnectionManager.registerConnectionEventListener(mc1)
> creates new TxConnectionEventListener and calls
> mc1.addConnectionEventListener
> - mc1 gets enlisted into the transaction,
> TxConnectionEventListener.enlist is called and mc1 is added
> into txToManagedConnectionMap
> - mc1.getConnection() is called to get sql connection, it
> gets conn1 through xaconn1.getConnection()
> BeanA calls BeanB
> - nothing special here
> BeanB allocates a connection and gets instance conn2 from the same
> xaconn1
> - TxConnectionManager.getManagedConnection gets mc1 from
> txToManagedConnectionMap
> - mc1.getConnection() is called to get sql connection, it
> gets conn2 through xaconn1.getConnection() and implicitly
> invalidates conn1 held by BeanA (see quote below)
> BeanB closes the connection and returns
> - nothing special
> BeanA tries to use the connection
> - SQLException("Logical handle no longer valid").
>
> A quote from JDBC 2.0 stdext, section 6.2.3 "Retrieving a Connection":
>
> <quote>
> An individual PooledConnection object will usually be asked to produce a
> series of Connection objects during its lifetime. Only one of these
> Connection objects may be open at a particular point in time. The
> connection pooling implementation must call
> PooledConnection.getConnection() each time a new reference to a
> pooledConnection is handed out to the JDBC application layer. Each call
> to PooledConnection.getConnection() must return a newly constructed
> Connection object that exhibits the default Connection behavior. Only
> the most recent Connection object produced from a particular
> PooledConnection is open. An existing Connection object is automatically
> closed, if the getConnection() method of its associated Pooled-
> Connection is called again, before it has been explicitly closed by the
> application. This gives the application server a way to �take away� a
> Connection from the application if it wishes, and give it out to someone
> else. This capability will not likely be used frequently in practice.
> </quote>
>
> Attached is a proposed fix. Hope this makes the problem clearer.
>
> David Jencks wrote:
> > I don't understand. Can you repeat your explanation of the problem
> clearly
> > indicating what is a ManagedConnection and what is a Connection? From
> your
> > description it looks like perhaps the problem is that we are reusing
> the
> > java.sql.Connection obtained from a XAConnection? This would not be a
> > problem with the trackConnectionByTx logic but with the xa wrapper.
> >
> > thanks
> > david jencks
> >
> >
> > On 2002.11.01 08:12:05 -0500 Igor Fedorenko wrote:
> >
> >>Hi,
> >>
> >>There is a problem with trackConnectionByTx in the current CVS version
> >>of JBoss 3.2 which occurs when two beans access the same datasource
> >>from the same transaction. I am not 100% sure about original
> >>implementation intends and would like to give others an opportunity to
> >>complain before I check in updated trackConnectionByTx logic.
> >>Consider the following example
> >>
> >>- BeanA allocates a connection and gets an instance conn1
> >>- BeanA calls BeanB
> >>- BeanB allocates a connection and gets the same instance conn1
> >>- BeanB closes the connection and returns
> >>- BeanA tries to use the connection and gets SQLException("Logical
> >>handle is closed").
> >>
> >>Updated trackConnectionByTx logic will return the
> >>same connection only if the connection has not been allocated yet
> >>(condition
> >>"BaseConnectionManager2.ConnectionListener.isManagedConnectionFree()");
> >>otherwise allocate and return new connection.
> >>
> >>Any objections?
>
> --
> Igor Fedorenko
> Think smart. Think automated. Think Dynamics.
> www.thinkdynamics.com
>
> Index: TxConnectionManager.java
> ===================================================================
> RCS file:
>/cvsroot/jboss/jbosscx/src/main/org/jboss/resource/connectionmanager/TxConnectionManager.java,v
> retrieving revision 1.2.2.1
> diff -u -r1.2.2.1 TxConnectionManager.java
> --- TxConnectionManager.java 12 Sep 2002 01:23:46
> -0000 1.2.2.1
> +++ TxConnectionManager.java 1 Nov 2002 16:06:11 -0000
> @@ -13,13 +13,13 @@
> import java.util.HashMap;
> import java.util.HashSet;
> import java.util.Iterator;
> +import java.util.List;
> import java.util.Map;
> import java.util.Set;
> -import javax.management.ObjectName;
> +
> import javax.naming.InitialContext;
> import javax.resource.ResourceException;
> import javax.resource.spi.ConnectionEvent;
> -import javax.resource.spi.ConnectionEventListener;
> import javax.resource.spi.ConnectionRequestInfo;
> import javax.resource.spi.ManagedConnection;
> import javax.resource.spi.ManagedConnectionFactory;
> @@ -34,8 +34,6 @@
> import javax.transaction.xa.XAResource;
> import javax.transaction.xa.Xid;
>
> -import org.jboss.system.Registry;
> -
> import org.jboss.logging.Logger;
>
> /**
> @@ -129,6 +127,7 @@
>
> private boolean localTransactions;
>
> + // maps tx => List of connections
> private final Map txToManagedConnectionMap = new HashMap();
>
> /**
> @@ -261,8 +260,25 @@
> ManagedConnection mc = null;
> synchronized (txToManagedConnectionMap)
> {
> - mc = (ManagedConnection)txToManagedConnectionMap.get(tx);
> + List conns = (List) txToManagedConnectionMap.get(tx);
> + if( conns != null )
> + {
> + Iterator i = conns.iterator();
> + while( i.hasNext() )
> + {
> + ManagedConnection conn = (ManagedConnection)
> i.next();
> + ConnectionListener listener =
> getConnectionEventListener(conn);
> + if( listener != null && listener instanceof
> TxConnectionEventListener
> + && ((TxConnectionEventListener)
> listener)._isManagedConnectionFree() )
> + {
> + mc = conn;
> + break;
> + }
> + }
> + }
> +// mc = (ManagedConnection)txToManagedConnectionMap.get(tx);
> }
> + // make sure that connection is not allocated by the client
> if (mc != null)
> {
> if (log.isTraceEnabled())
> @@ -443,7 +459,13 @@
> //Here we actually track the cx by tx.
> synchronized(txToManagedConnectionMap)
> {
> - txToManagedConnectionMap.put(currentTx,
> this.getManagedConnection());
> + List conns = (List)
> txToManagedConnectionMap.get(currentTx);
> + if( conns == null )
> + {
> + conns = new ArrayList();
> + txToManagedConnectionMap.put(currentTx, conns);
> + }
> + conns.add(this.getManagedConnection());
> }
>
> } // end of if ()
> @@ -576,7 +598,15 @@
> {
> synchronized(txToManagedConnectionMap)
> {
> - txToManagedConnectionMap.remove(currentTx);
> + List conns = (List)
txToManagedConnectionMap.get(currentTx);
> + if( conns != null )
> + {
> + conns.remove(ce.getConnectionHandle());
> + if( conns.isEmpty() )
> + {
> + txToManagedConnectionMap.remove(currentTx);
> + }
> + }
> }
> }
> currentTx = null;
> @@ -595,6 +625,10 @@
> {
> return false;
> } // end of if ()
> + return super.isManagedConnectionFree();
> + }
> + boolean _isManagedConnectionFree()
> + {
> return super.isManagedConnectionFree();
> }
>
>
-------------------------------------------------------
This sf.net email is sponsored by: See the NEW Palm
Tungsten T handheld. Power & Color in a compact size!
http://ads.sourceforge.net/cgi-bin/redirect.pl?palm0001en
_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development