开发者

Should I close JNDI-obtained data source?

Update: Apparently Tomcat, starting with 7.0.11, closes the DataSource for you, so it's not available in the webapp's contextDest开发者_StackOverflow社区royed. See: https://issues.apache.org/bugzilla/show_bug.cgi?id=25060

Hi,

I'm using Spring 3.0 and Java 1.6.

If I get a data source this way:

<bean id="dataSource" class="my.data.Source" destroy-method="close">
    <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
    <property name="url" value="jdbc:oracle:thin:@localhost:1521:home"/>
    <property name="username" value="user"/>
    <property name="password" value="pw"/>
</bean>

then the data source is closed when the bean is destroyed.

If I get the data source like this:

<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/db" />

then do I have to explicitly close the data source in my contextDestroyed listener?

Thanks,

Paul


I disagree. I would add a listener to your web.xml and implement the contextDestroyed() method. This method will get called by your web container/app server when the web app is destroyed or undeployed. Within the contextDestroyed(), I would close the datasource.

inside the web.xml

<listener>
   <listener-class>util.myApplicationWatcher</listener-class>
</listener>

The code:

package util;

public class myApplicationWatcher implementes ServletContextListener
{
  public void contextInitialized(ServletContextEvent cs)
  {
      // This web application is getting started

      // Initialize connection pool here by running a query
      JdbcTemplate jt = new JdbcTemplate(Dao.getDataSource() );
      jt.queryForInt("Select count(col1) from some_table");
  }

  public void contextDestroyed(ServeletContextEvent ce)
  {
      // This web application is getting undeployed or destroyed 

      // close the connection pool
      Dao.closeDataSource();
  }
}

public class Dao
{
  private static DataSource ds;
  private static bDataSourceInitialized=false;
  private static void initializeDataSource() throws Exception
  {
    InitialContext initial = new InitialContext();

    ds = (DataSource) initial.lookup(TOMCAT_JNDI_NAME);

    if (ds.getConnection() == null)
    {
      throw new RuntimeException("I failed to find the TOMCAT_JNDI_NAME");
    }

    bDataSourceInitialized=true;
  }

  public static void closeDataSource() throws Exception
  {
    // Cast my DataSource class to a c3po connection pool class
    // since c3po is what I use in my context.xml
    ComboPooledDataSource cs = (ComboPooledDatasource) ds;

    // close this connection pool
    cs.close();
  }

  public static DataSource getDataSource() throws Exception
  {
    if (bDataSourceInitialized==false)
    {
      initializeDataSource();
    }

    return(ds);
  }
}


No. The DataSource here is managed by the remote JNDI container, and it's that container's job to manage the lifecycle of the DataSource. Spring just makes use of it, it doesn't manage it.

Even if you wanted to, you couldn't - DataSource has no close() method, or anything like it.


When you get the data source through a JNDI lookup it a shared resource - configured in your container. It is managed by the container and not by the application, so it is not required (there is no way) to close it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜