Bugs item #620262, was opened at 2002-10-08 16:44
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=376685&aid=620262&group_id=22866
Category: JBossCX
Group: v3.0 Rabbit Hole
Status: Open
Resolution: Fixed
Priority: 5
Submitted By: Marko Strukelj (mstruk)
Assigned to: David Jencks (d_jencks)
Summary: Trying to change Tx in enlist exception
Initial Comment:
When doing very intensive remote calls via statefull
session, using the database with user managed
transactions I often get this error:
2002-10-03 15:51:16,000 WARN
[org.jboss.resource.connectionmanager.LocalTxConnecti
onManager$LocalConnectionEventListener] in Enlisting
tx, trying to change tx. illegal state: old:
TransactionImpl:XidImpl [FormatId=257,
GlobalId=brutus//233, BranchQual=], new:
TransactionImpl:XidImpl [FormatId=257,
GlobalId=brutus//234, BranchQual=], cel:
org.jboss.resource.connectionmanager.LocalTxConnecti
onManager$LocalConnectionEventListener@1f8d0a4
2002-10-03 15:51:16,000 ERROR [STDERR]
java.lang.IllegalStateException: Trying to change Tx in
enlist!
2002-10-03 15:51:16,000 ERROR [STDERR] at
org.jboss.resource.connectionmanager.LocalTxConnecti
onManager$LocalConnectionEventListener.enlist
(LocalTxConnectionManager.java:309)
2002-10-03 15:51:16,000 ERROR [STDERR] at
org.jboss.resource.connectionmanager.LocalTxConnecti
onManager.managedConnectionReconnected
(LocalTxConnectionManager.java:255)
2002-10-03 15:51:16,000 ERROR [STDERR] at
org.jboss.resource.connectionmanager.BaseConnection
Manager2.allocateConnection
(BaseConnectionManager2.java:534)
2002-10-03 15:51:16,000 ERROR [STDERR] at
org.jboss.resource.connectionmanager.BaseConnection
Manager2$ConnectionManagerProxy.allocateConnection
(BaseConnectionManager2.java:812)
2002-10-03 15:51:16,000 ERROR [STDERR] at
org.jboss.resource.adapter.jdbc.local.LocalDataSource.g
etConnection(LocalDataSource.java:102)
It only happens when there is severe concurent use of
the database. But it does happen a lot.
What seems to happen is this:
Thread 1:
userTransaction.begin();
Connection c=ds.getConnection(); // lets
call this Connection1
// ... use connection
c.close(); // close connection
// now don't commit transaction yet
Thread 2:
userTransaction.begin();
Connection c=ds.getConnection(); //
KABOOOM! Exception happens here.
Exception happened because Connection1 was trying to
be returned - the same connection that was used by
another thread.
In the time between returning a connection to the pool
and calling commit on UserTransaction the same
connection is checked out to another thread.
I am trying to make an example to reproduce the bug.
So far the only way I can reproduce it is on my
production system with full application deployed.
----------------------------------------------------------------------
>Comment By: Marko Strukelj (mstruk)
Date: 2002-10-24 12:12
Message:
Logged In: YES
user_id=625403
It seems to work now. I don't see the 'Trying to change Tx in
enlist' exception any more.
I checked out Branch-3_0, built what claimed to be JBoss-
3.0.4RC1, put in the old code that caused exceptions before.
It runs out of connections now but this is due to GC
dynamics.
For all I can say, the bug is fixed.
----------------------------------------------------------------------
Comment By: David Jencks (d_jencks)
Date: 2002-10-23 01:25
Message:
Logged In: YES
user_id=60525
I think there was a race between close and commit checking
if a connection could be returned and returning it to the
pool. I've added some synchronization to the 3.0 branch to
try to fix this. Please try it out and see if is fixed,
then I will do something similar in the other branches.
If you are using a later branch please let me know, I will
check in something there for you to test.
Thanks
david jencks
----------------------------------------------------------------------
Comment By: Marko Strukelj (mstruk)
Date: 2002-10-14 16:33
Message:
Logged In: YES
user_id=625403
Now I finally got to the bottom of this. Turns out the problem
that the two threads get the same connection from the pool is
due to connection being returned to the pool twice.
I have a situation where connection is referenced by another
object (ormsession object that represents an object relational
mapper). This object is created upon request and it retrieves
a database connection from a DataSource for its internal use.
ormsession calls connection.close() in its finalize() and it
does this through Finalizer thread - bad idea.
Before this happens (or maybe after - I'm not sure) ut.commit
() is done in the thread that got the ormsession before and
this again causes the managed connection to be returned to
the pool.
The problem is that the described chain of events causes an
inconsistent state in InternalManagedConnectionPool.
Afterwards there are two different MCHolder instances
referencing the same ManagedLocalConnection instance.
This makes it possible that later that same MC is checked
out twice.
During this exploration I also realized that I am using the
connection pool in such a way that "not participating properly
in this management scheme." condition is always present. I
have an MBean with its own thread and it is accessing
DataSource directly without going through interceptors. Doing
it this way is very convenient for me and it seems to have
been working properly thus far. It also worked in jboss 2.4.3. I
hope it stays that way and that future versions of jboss don't
break this.
The bug on my part was extremely difficult to find. It would be
a lot easier if InternalManagedConnectionPool threw
Exception to point out that a thread that's putting the
connection back is not the one that took it out.
Or maybe we could just do some other check.
InternalManagedConnectionPool.returnConnection()
executes this statement to return managed connection to the
pool:
mcs.addLast(new MCHolder(mc));
it could execute something like this instead:
for (Iterator i = mcs.iterator(); i.hasNext(); )
{
MCHolder mch = (MCHolder)i.next();
if (mch.getMC() == mc) throw new
RuntimeException();
}
mcs.addLast(new MCHolder(mc));
RuntimeException is necessary because method throws no
Exception - but doing it like this is kind of ugly itself so the
best thing to do might be to just leave it as it is and change
nothing.
I am questioning myself now whether this qualifies as a bug
or not. The fact is that illegal use on my part caused the
situation to develop. On the other hand I would expect an
application server or specifically the pools to not make 2
connections from one no matter how wrong I use it.
So I leave it to you to decide and won't change it to Not-a-Bug
just yet.
----------------------------------------------------------------------
Comment By: Marko Strukelj (mstruk)
Date: 2002-10-11 16:08
Message:
Logged In: YES
user_id=625403
Looks like my initial diagnosis was slightly incorrect.
What I see happening when I put logging at strategic places
is that two threads try to get the same connection out at the
same time. One succeeds the other one gets exception.
It must therefore be a synchronization problem.
I'll try to do some more debugging and to find the offending
spot.
----------------------------------------------------------------------
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=376685&aid=620262&group_id=22866
-------------------------------------------------------
This sf.net email is sponsored by: Influence the future
of Java(TM) technology. Join the Java Community
Process(SM) (JCP(SM)) program now.
http://ad.doubleclick.net/clk;4729346;7592162;s?http://www.sun.com/javavote
_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development