Parameshwara,

On 8/1/25 12:15 AM, Parameshwara Bhat wrote:
I am working on a task of migrating a  running a JSP/JSF application on tomcat-6.0 to tomcat 9.0

My installation of tomcat-9.0.87 is on Opensuse-Leap-15.6. Database is postgresql 17, using postgresql-42.7.7.jar for driver.

I am able to run legacy application on tomcat-9.0.87 after making following changes ( picked up from tomcat-9.0 docs) to application's connection code.

    try {
            InitialContext cxt = new InitialContext();
            /*if ( cxt == null ) {
            throw new Exception("Uh oh -- no context!");
            }*/
            DataSource ds = (DataSource) cxt.lookup(
    "java:/comp/env/jdbc/public_PostgreSQL" );
            /*if ( ds == null ) {
            throws new Exception("Data source not found!");
            }*/
            try {
            this.con = ds.getConnection();
            } catch (SQLException ex) {
            ex.printStackTrace();
            }
          } catch (NamingException e)  {
            e.printStackTrace();
          }

        /*        this.con = DriverManager.getConnection(url,
        username, password); */

You are never closing your connections, so you are leaking a connectin from the pool every time this code runs.

I agree with Felix's assertion that using this.conn is likely a mistake. While JDBC objects are theoretically thread-safe, they are not practically so. For example, if one request (A) begins a transaction while another request (B) is not expecting it, changes to the database from request (B) might end up being rolled back if request (A) fails and triggers a roll-back.

Besides, if you only need a single connection, what are you using a pool for?

Or is this some kind of data-access object which is short-lived? Your code gives no context.

I believe Tomcat's default behavior is to return the same DataSource object each time you fetch it from JNDI, but I believe a sterict reading of the specification suggests that the container is supposed to give you a *new DataSource every time* which means that each time you get the DataSource, you are requesting a completely new, distinct pool of connections from the container.

I would recommend that you only obtain a DataSource from the container a single time during application startup, and then use that (pooled) DataSource repeatedly from your application.

My context.xml content is below.

    <?xml version="1.0" encoding="UTF-8"?>
    <Context path="/ERP">
      <Resource auth="Container"
    driverClassName="org.postgresql.Driver" maxTotal="40" maxIdle="20"
    maxWaitMillis="-1" name="jdbc/public_PostgreSQL"
    password="kapital" type="javax.sql.DataSource"
    url="jdbc:postgresql://localhost:5444/das" username="das"/>
    </Context>

Set maxTotal="1" for development and testing. Also, enable "abandoned connection tracking". See the documentation for how to do that, and you'll discover all your resource leaks fairly quickly.

-chris


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to