From: Igor F. <ife...@th...> - 2002-11-01 16:29:17
|
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 |