Devo fechar a fonte de dados obtida pelo JNDI?
-
29-10-2019 - |
Pergunta
Atualizar:Aparentemente o Tomcat, começando com 7.0.11, fecha o DataSource para você, então ele não está disponível no contextDestroyed do webapp.Ver: https://issues.apache.org/bugzilla/show_bug.cgi?id=25060
Oi,
Estou usando Spring 3.0 e Java 1.6.
Se eu obtiver uma fonte de dados desta forma:
<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>
então a fonte de dados é fechada quando o bean é destruído.
Se eu obtiver a fonte de dados assim:
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/db" />
então preciso fechar explicitamente a fonte de dados em meu ouvinte contextDestroyed?
Obrigado,
Paulo
Solução
Eu discordo.Gostaria de adicionar um ouvinte ao seu web.xml e implementar o método contextDestroyed ().Este método será chamado por seu servidor de contêiner / aplicativo da web quando o aplicativo da web for destruído ou desimplantado.Dentro de contextDestroyed (), gostaria de fechar a fonte de dados.
dentro do web.xml
<listener>
<listener-class>util.myApplicationWatcher</listener-class>
</listener>
O código:
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);
}
}
Outras dicas
Não.O DataSource
aqui é gerenciado pelo contêiner JNDI remoto, e é função desse contêiner gerenciar o ciclo de vida do DataSource
.O Spring apenas faz uso disso, não gerencia.
Mesmo se você quisesse, você não poderia - DataSource
não tem close()
método ou algo parecido.
Quando você obtém a fonte de dados por meio de uma pesquisa JNDI, é um recurso compartilhado - configurado em seu contêiner.Ele é gerenciado pelo container e não pelo aplicativo, portanto não é necessário (não há como fechá-lo).