Thank you very much for your detailled help.
now, after approx. 5 days bug-searching, we found the problem.
it was a connection leak:-(

the controller, who handles the connections, generated new
connections and didn`t automaticly delete it. so if you didn`t close them manually in the ActionClass, the connection was still alive.
at one point of the application, we didn`t close them manually.
normally no problem, if the controller manages the handling correctly. so we inserted a finalize()-method to assure, that connection is closed and set to null automaticly.


like this:

public class Controller
{
   private DataSource _dataSource = null;
   private Connection _conn = null;

   public Controller(DataSource dataSource)
   {
        setDataSource(dataSource);
        if ( null != getDataSource() )
        {
            _conn = newConnection();
        } else {
                // log anything
        }
   }

public DataSource getDataSource() {return _dataSource;}
protected void setDataSource(DataSource dataSource) {_dataSource=dataSource;}
public Connection getConnection() {if(null==_conn) newConnection(); return _conn;}
protected void setConnection(Connection conn) {_conn=conn;}


   private Connection newConnection()
   {
        if (null==getDataSource())
        {
                // log anything
        }
        else
        {
                synchronized(getDataSource())
                {       
                    try {
                        setConnection(getDataSource().getConnection());
                    } catch (SQLException e) {
                                // log anything
                    }
                }               }
        return _conn;
   }

   public void closeConnection()
   {
                if (null==_conn)
                {
                    return;
                }
        try {
                        if(!_conn.isClosed()) _conn.close();
        } catch (SQLException e) {
                        // log anything
        } finally {
                        _conn = null;
       }
   }

   public void destroyConnection()
   {
                if (null!=_conn)
                {
                        closeConnection();
                }
   }

   protected void finalize() throws Throwable
   {
           this.destroyConnection();
   }

---------------------------------------------------------------------------
On Tue, 21 Oct 2003 01:35:26 -0700, Max Cooper <[EMAIL PROTECTED]> wrote:

It might be deadlock of a "dining philosophers" nature. Consider a request
that takes 2 simultaneous database connections to process. You have a db
connection pool with 5 connections in it. If 5 of these
2-connection-requiring requests come in at once, each request-handler thread
might grab one connection from the pool. And then wait forever for another
connection to become available. Your application has dead-locked. We ran
into this problem on a project that I worked on.


Possible solutions:

1. If you have any db connection leaks, fix them. Draining the db connection
pool with a leak will quickly leave you with no connections and hung
requests.


2. Configure your db connection pool to grow above the size limit when it
needs to. In the example above, the pool would grow to 10 connections (even
if the limit is 5) to handle the requests. The extra connections would be
closed when they are returned to the pool, shrinking the pool size back down
to 5 connections.


3. Limit your HTTP requests to requiring only one db connection at a time.
This allows you to use a db connection pool with a fixed size-limit without
risking deadlock. You can code your app carefully so as to never need more
than one simultaneous connection when servicing a request, but that can be
very tricky to do in some cases. Another option is to create some mechanism
that will store a reference to any existing db connection being used by a
thread with the thread itself so that one thread can never use more than one
db connection at a time. At the end of the request, you can ensure that the
connection associated with a thread (if any) is released back to the pool (a
Filter works great for this). Here's some pseudo-code to illustrate:


Connection getConnection() {
connection = get connection from thread
if (connection is null) {
connection = get connection from pool
store reference to connection in thread
set connection-user reference count in thread to 1
} else {
increment connection-user reference count in thread
}
return connection
}

void releaseConnection() {
decrement connection-user reference count in thread
connection-users = get connection-user reference count from thread
if (connection-users is zero) {
return connection to pool
}
}

To make this work more nicely with other components, you could create your
own DataSource and use a dynamic proxy class to wrap the connection objects
so that the releaseConnection()-style processing would occur when the client
calls .close() on the connection. You may also want to have a servlet filter
class release any connections held by a thread when the HTTP request
processing is finished. This would ensure that db connection leaks don't
exhaust your supply of database connections, although obviously it would be
ideal to code everything perfectly so there are no leaks.


QUESTION: Does anyone know of any DataSource implementations that do this
kind of one-connection-per-thread processing? It could be implemented
generically to wrap another DataSource and use dynamic proxy wrappers on the
connection objects. This is a very real problem for web apps, and it would
be nice to have a standard solution. My project team ran into this problem
and wrote our own (proprietary) solution like I have outlined here, but if
someone knows of some open-source library that does this kind of processing,
it would be great if they would post it.


4. Configure your db connection pool to fail when there aren't enough
connections to hand out. In this case, all 5 of those HTTP requests would
fail when they try to get another connection. Having logic that would wait
and then try to get a connection again would still leave your app vulnerable
to deadlock, since no more db connections would ever become available, so it
is best to have the HTTP request fail when this occurs (and release whatever
connections they were holding). However, this option may be unacceptable
since the reason for the HTTP request to fail will be mysterious to your
users.


-Max

-----Ursprungliche Nachricht-----
Von: Nino Garbin [mailto:[EMAIL PROTECTED]
Gesendet: Montag, 20. Oktober 2003 13:32
An: [EMAIL PROTECTED]
Betreff: Application hangup??


dear pros,


i have a anoying problem with an application using  the actual struts on
tomcat 4.1.27 getting data from an mysql-db.

my application works fine doing several requests to call some actions.
the application is framed (navigation, content), each frame calls his own
action.


at no special point, the application hangs up while calling an action,
that
was called and worked fine before. a look on the heapsize doesn`t
show any suspicious changes. the "hangup" doesn`t seems to depend on the
heapsize. the webserver is still ok at this moment, other applications
still work fine. only if i call an action of the current application, the
constructor of this action is called and after this nothing seems to
happen.


no error message in any logfile, nothing. only a blank screen.

has anyone an idea? is it probably a connection-problem with the db?
or do you know about similar problems in other projects?

thank you very much for help,

nino




--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]






-- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/


--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to