2010-06-29 8 views
0

Cet article est destiné à être moins une question et plus une confirmation que je fais les choses correctement. J'ai vu beaucoup de posts similaires mais je ne suis pas sûr de bien comprendre tout ce qui a été dit. Le problème est que, après un certain laps de temps, je reçois une exception en essayant d'établir une connexion à ma base de données Oracle. (J'utilise Tomcat 6.0 et Spring)Regroupement de connexions Java Oracle - Exclue Connection Connection

Auparavant, j'avais la configuration suivante:

private PoolDataSource poolDataSource = null; 

public MainDAOImpl(String url, String username, String password) 
     throws Exception 
{ 
    poolDataSource = PoolDataSourceFactory.getPoolDataSource(); 

    try 
    { 
     poolDataSource.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource"); 
     poolDataSource.setURL(url); 
     poolDataSource.setUser(username); 
     poolDataSource.setPassword(password); 
    } 
    catch(SQLException e) 
    { 
     ... 
    } 
} 

public List<Object> getValues(String query) 
{ 
    Connection connection = null; 
    PreparedStatement preparedStatement = null; 

    try 
    { 
     connection = poolDataSource.getConnection(); 
     preparedStatement = connection.prepareStatement(query); 

     ... 
    } 
    catch(SQLException e) 
    { 
     ... 
    } 
    finally 
    { 
     //close connections 
    } 
} 

Cependant, parfois preparedStatement = connection.prepareStatement(query); un SQLException jeté avec un message "Exception fermée".

Il est important de noter que le constructeur MainDAOImpl n'est appelé qu'une seule fois par redémarrage du serveur (sa dépendance est injectée via Spring).

J'ai récemment changé ma configuration comme ceci:

private DataSource dataSource = null; 

public MainDAOImpl() 
     throws Exception 
{ 
    try 
    { 
     Context initContext = new InitialContext(); 
     Context envContext = (Context)initContext.lookup("java:/comp/env"); 
     dataSource = (DataSource)envContext.lookup("jdbc/myOracleConn"); 
    } 
    catch(NamingException e) 
    { 
     ... 
    } 
} 

et poolDataSource.getConnection()-dataSource.getConnection().

J'ai aussi ajouté à mon contexte, les ressources suivantes dans Tomcat:

<Resource name="jdbc/myOracleConn" auth="Container" 
      type="javax.sql.DataSource" 
      driverClassName="oracle.jdbc.OracleDriver" 
      url="<myURL>" 
      username="<myUsername>" password="<myPassword>" 
      maxActive="20" maxIdle="10" maxWaith="-1" /> 

Ce qui suit essentiellement http://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html mot pour mot.

Tout semble fonctionner. Ma question est, est-ce que ces changements vont résoudre mon problème de connexion fermée ou y a-t-il quelque chose de différent à faire?

Merci,

B.J.

Répondre

1

Tout d'abord, si vous utilisez Spring pour l'injection de dépendance, je vous recommande d'utiliser également DI pour injecter les dépendances de l'OAC en elle. En d'autres termes, votre DAO devrait recevoir un DataSource, plutôt que l'implémentation de DAO en sachant 1) quel type de DataSource construire ou 2) comment et où le rechercher dans JNDI. Printemps can handle JNDI lookups pour vous.

Je vous recommande également d'utiliser le JdbcTemplate de Spring, car il constitue un excellent complément pour les appels JDBC bruts. Enfin, l'exception réelle que vous obtenez est peut-être due au fait que le serveur de base de données ferme des connexions longues. Vous ne savez pas quelle implémentation de pool de connexions vous utilisez, mais dans commons-dbcp il y a an option for a "validationQuery" que le pool va exécuter avant de renvoyer une connexion pour vérifier que la connexion est toujours valide. Je suis sûr que la plupart des autres pools fournissent des fonctionnalités similaires, que je recommande ici - de cette façon, votre DAO ne reçoit jamais de connexions périmées de la piscine.