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