-
1. Re: Why is jboss closing my connection?
adrian.brock Jun 15, 2007 2:13 PM (in response to teknokrat)FAQ
-
3. Re: Why is jboss closing my connection?
teknokrat Jun 16, 2007 6:19 AM (in response to teknokrat)Ok, thanks. Is there a way to switch this off on a per connection factory level? I would like to get the benefits of the checking for database connections but not on my own session based connections.
Also, just out of curiosity, what is the heuristic that jboss uses to decide that a connection has been checked out of the pool long enough and needs closing?
cheers -
4. Re: Why is jboss closing my connection?
adrian.brock Jun 18, 2007 9:50 AM (in response to teknokrat)"teknokrat" wrote:
Ok, thanks. Is there a way to switch this off on a per connection factory level? I would like to get the benefits of the checking for database connections but not on my own session based connections.
As per the docs:
debug=false in jbossjca-service.xml
But then avoiding connection leakage becomes your problem. :-)
As stated many times in this forum. Holding one connection per ejb instance
is an anti-pattern and a totally inefficient use of resources.
The connections are already pooled (and cached at the transaction level)
by JCA which leads to a much more efficient use of resources.// CMT Required Transaction public void doSomething() { ConnectionFactory cf = ... Connection c1 = cf.getConnection(); // Handle Connection real1 = c1.getRealConnection(); // Real Connection c2 = cf.getConnection(); // Handle Connection real2 = c2.getRealConnection(); // Real assert c1 != c2; // Handles are not the same instance assert real1 == real2; // But you always use the same real/underlying connection in the same transaction }
"teknokrat" wrote:
Also, just out of curiosity, what is the heuristic that jboss uses to decide that a connection has been checked out of the pool long enough and needs closing?
In a transaction - the end of the transaction
Otherwise the end of request (EJB method/Web invocation) -
5. Re: Why is jboss closing my connection?
teknokrat Jun 18, 2007 12:03 PM (in response to teknokrat)I would love to do things that way. Here lies my problem. I have a stateful service. The service needs to keep a TCP connection open to an external resource. Everytime I get a connection from the pool, it must be exactly the same one I used before for this session. I tried to play around with the BySubject and ByApplication settings but found it easier to just open a connection at the beginning and close it on remove.
If there are better ways to do this I am all ears.
thanks for the help. -
6. Re: Why is jboss closing my connection?
adrian.brock Jun 18, 2007 12:38 PM (in response to teknokrat)"teknokrat" wrote:
If there are better ways to do this I am all ears.
Use a transaction.
What you have is a unit of work.
startWork();
doStuff();
endWork();
JTA Transactions are natural units of work.
You can mark when the work starts and when it finishes.
More importantly, you can decide when it should timeout and resources get released.
Don't get confused about performance. A JTA transaction is just a thread
local marker, its not "heavy" like a real jdbc transaction.
It can become "heavy" if you enlist something like a jdbc connection
in the JTA transaction.
Stateful sessions are also units of work
but they have some bad semantics in terms of resource allocation.
e.g. Suppose the client starts a session, you allocate a tcp/ip connection
(a limited resource) per session, but the client then vanishes, e.g. if it is a user
interface they go to lunch or go home without ending the session (properly).
After a certain period of inactivity JBoss will passivate the session (write it to disk)
after a further period of inactivity it will remove the session altogether.
Question: How are you going to recover the tcp/ip connection if the session is passivated
and then reactivated? You certainly can't serialize a tcp/ip socket.
For the same reason, you can't replicate the session across a cluster if you
want the session to failover.
Another bad feature of SFSB is that a serious error (an EJB/RuntimeException)
will mean that ejbRemove() is NOT invoked. That means there is no
way for the EJB instance to tell the server to release the resources it allocated.
You will leak connections!
The EJB spec says you need to do some extra work to cater for this situation,
but this is usually hard to do.
What this shows is that in general it is bad idea to have the EJBs control
resource allocation. You should let the server do it. If you need to use the
same connection across requests, use the JTA transaction notion
to define what those requests are and let the server "cache" the connection
against the transaction.
It's called "Transaction Stickiness" on the WIKI page describing the pooling.
Anyway, that's enough free consulting. :-) All I can say is that you have been
warned that what you are doing is anti-pattern and I've listed some of the
main reasons why, plus given you an idea of how to redefine what you
are doing as a "unit of work" with better semantics.
And I didn't even mention the horrible BMT SFSB semantics. :-) -
7. Re: Why is jboss closing my connection?
teknokrat Jun 18, 2007 1:05 PM (in response to teknokrat)Ok, OK, you've convinced me ;) I will look into using the container connection management to find me the right connection when I need it.
The reason I never considered transaction stickiness is that I am unsure whether using a transaction to demarcate a long-lasting-over-serveral-requests session is good form or not. Think of a telnet session here. Is it acceptable to use a tranasction to demaracate user activity from logon to logoff? That is the situation I effectively have.
Thank you -
8. Re: Why is jboss closing my connection?
adrian.brock Jun 19, 2007 10:38 AM (in response to teknokrat)The point I'm making is that you wouldn't do it that way (demarcate logon/logoff).
A user can logon and not do anything. You are wasting resources.
Instead you would allocate a connection for a unit of work (e.g. upload/download some files).
For each unit of work, you would "reauthenticate" based on the CRI or Subject.
That way you get maximum sharing of connections and you don't have
unused connections lying around when they are not being used.
The number of open connections is directly related to the number of active units of work,
not the number of SFSBs a lot of which could be idle.
This would be most efficient if the backend supports something like session suspension
as some telnet servers do.
Related to that is (if you are writing the back end yourself), you would be better using the
XAResource interface and storing the session against the XID on the backend server.
That way you can use "interleaving" where you start the session on one connection
suspend it (close() - returning the connection to the pool for somebody else to use)
and resume it on a different physical connection (or the same connection)
when you need it again.
e.g. psuedo codeConnectionFactory cf = ... Connection c = cf.getConnection(); // Allocate connection from pool - start the session - XAResource.start(xid, TMNOFLAGS); Object data; try { data = c.download(); } finally { // Return the connection to the pool - suspend the session - XAResource.suspend(xid); c.close(); } // Do some long running process, we don't need to have the connection for this // so let somebody else use it! Object result = calc(data); Connection c = cf.getConnection(); // Reget a connection - resume the session - XAResource.start(xid, TM_RESUME); try { c.upload(result); } finally { c.close(); }
Finally, you also have greater ability to reap connections that are idle during low load periods. -
9. Re: Why is jboss closing my connection?
teknokrat Jun 21, 2007 11:44 AM (in response to teknokrat)This is very interesting Adrian. I appreciate the time you have taken to explain all of this to me. However, let me state my problem more concretely so that this discussion doesn't become too theoretical.
I am developing a JCA connector to be used against a third-party's system. This system is a game server that plays various well known card games. The system is a legacy system that I have no control over. Whereas the system does support session disconnects/reconnects these are very expensive. The protocol is very chatty and requires you to do things like look up various servers for information, do public key exchange, etc. As such, i feel that doing a re-authentication on every request would be too costly ( I must run some benchmarks of course ).
Thats why I can't think of anything better than partitioning the connection pool ByApplication with max/min connections per sub pool being 1.
Thanks for the help