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

Reply via email to