Должен ли я закрыть JNDI-полученный источник данных? - PullRequest
8 голосов
/ 23 марта 2011

Обновление: по-видимому, Tomcat, начиная с 7.0.11, закрывает для вас источник данных, поэтому он недоступен в contextDestroyed веб-приложения.См .: https://issues.apache.org/bugzilla/show_bug.cgi?id=25060

Привет,

Я использую Spring 3.0 и Java 1.6.

Если я получу источник данных таким образом:

<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>

, тогда источник данных закрывается, когда бин уничтожен.

Если я получу источник данных следующим образом:

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

, тогда я должен явно закрыть источник данных вмой контекст уничтожен слушателем?

Спасибо,

Пол

Ответы [ 3 ]

5 голосов
/ 24 марта 2011

Я не согласен. Я бы добавил слушатель в ваш web.xml и реализовал метод contextDestroyed (). Этот метод будет вызываться вашим веб-контейнером / сервером приложений, когда веб-приложение будет уничтожено или развернуто. Внутри contextDestroyed () я бы закрыл источник данных.

внутри web.xml

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

Код:

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);
  }
}
4 голосов
/ 23 марта 2011

Нет.DataSource здесь управляется удаленным контейнером JNDI, и задачей этого контейнера является управление жизненным циклом DataSource.Spring просто использует это, но не управляет им.

Даже если бы вы захотели, вы бы не смогли - DataSource не имеет close() метода или чего-либо подобного.

1 голос
/ 23 марта 2011

Когда вы получаете источник данных через поиск JNDI, это общий ресурс, настроенный в вашем контейнере. Он управляется контейнером, а не приложением, поэтому закрывать его не требуется (нет способа).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...