2010-06-29 102 views
0

這篇文章的目的不是爲了一個問題,而是爲了確認我正確地做事。我見過很多類似的帖子,但我不確定自己完全理解了所說的一切。Java Oracle連接池 - 關閉連接異常

問題是,經過一段時間後,我試圖建立到oracle數據庫的連接時出現異常。 (我使用Tomcat 6.0和Spring)

以前,我有如下配置:

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

但是,有時preparedStatement = connection.prepareStatement(query);拋出一個SQLException與 「封閉異常」 的消息。

重要的是要注意,每個服務器重新啓動(它通過Spring注入的依賴項)MainDAOImpl的構造函數只被調用一次。

我最近改變了我的設置,像這樣:

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) 
    { 
     ... 
    } 
} 

poolDataSource.getConnection()dataSource.getConnection()

我還添加了以下資源,以我的上下文中的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" /> 

這基本上遵循http://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html字對字。

一切似乎都在工作。我的問題是,這些更改是否會解決我的關閉連接問題,還是存在與我需要做的不同的事情?

感謝,

B.J.

回答

1

首先,如果你正在使用Spring依賴注入,我建議你也可以使用DI注入DAO的依賴性進去。

換句話說,你的DAO應該有一個注入到其中的數據源,而不是DAO實現要麼知道1)要構造什麼類型的數據源,要麼2)在JNDI中查找它的方式和位置。春季can handle JNDI lookups爲您服務。

我還建議使用Spring的JdbcTemplate,因爲它可以讓您自己對原始JDBC調用進行很好的封裝。

最後,您得到的實際異常可能只是因爲數據庫服務器正在關閉長時間打開的連接。不知道您正在使用哪個連接池實施,但在commons-dbcp中有an option for a "validationQuery"池將在返回連接之前執行以驗證連接是否仍然有效。我相信大多數其他池提供類似的功能,我會在這裏推薦 - 這樣,您的DAO永遠不會從池中接收過時的連接。