2016-10-11 33 views
0

對於Oracle Pooling連接,我使用oracle.jdbc.pool.OracleDataSource,但似乎連接在數據庫中保持活動狀態。今天,我在連接到Oracle數據庫得到了一個錯誤:Spring oracle數據源不會破壞連接

ORA-12516:TNS:監聽程序無法找到匹配協議棧

可用的處理器和我被我們的數據庫管理員告訴記者,太多打開的連接從我的應用程序保持「IDLE」模式。

我用ojdbc7:

<dependency> 
    <groupId>com.oracle</groupId> 
    <artifactId>ojdbc7</artifactId> 
    <version>12.1.0.1</version> 
</dependency> 

春applicationContext.xml文件:

<bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource" destroy-method="close"> 
    <property name="URL" value="${jdbc.url}" /> 
    <property name="user" value="${jdbc.username}" /> 
    <property name="password" value="${jdbc.password}" /> 
    <property name="connectionCachingEnabled" value="true" /> 
</bean> 

的數據庫連接類:

import java.sql.Connection; 
import java.sql.SQLException; 
import javax.sql.DataSource; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Repository; 

@Repository 
public class DbConnect { 

    @Autowired 
    private DataSource dataSource; 

    public Connection getConnection() throws SQLException { 
     return dataSource.getConnection(); 
    } 
} 

而且我用JDK7的嘗試,與資源的語法我的dao級別連接:

@Autowired 
private DbConnect dbConnect; 

public List<User> getAllUsers() { 
    List<User> list = new ArrayList<>(); 

    try(Connection connection = dbConnect.getConnection()) { 
     try(PreparedStatement preparedStatement = connection.prepareStatement("select * from V_USERS t")) { 
      try(ResultSet resultSet = preparedStatement.executeQuery()) { 
       while(resultSet.next()) { 
        list.add(RowFetcher.fetchUser(resultSet)); 
       } 
      } 
     } 
    } 
    catch(Exception e) { 
     log.error(e.getMessage(), e); 
    } 

    return list; 
} 

無法弄清楚實際問題在哪裏。我應該使用c3p0而不是OracleDataSource嗎?在我的代碼中有沒有ojdbc7中的錯誤或錯誤?

提前致謝!

+1

您應該發佈'DbConnect'代碼 –

+0

我已編輯帖子。請參閱更改 – 0bj3ct

+0

dba認爲適合多少個連接,以及Oracle數據源中的默認設置是什麼。 – KarlP

回答

1

.T工作的池的要點是保持打開狀態。不過,我不確定OracleDataSource是實際的池還是你需要OracleConnectionPoolDataSource

而不是使用普通的Oracle池,我建議使用HikariCPconfiguration options上的頁面和默認值。

在這種情況下,你的數據源看起來像

<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"> 
    <property name="datasourceClassName" value="oracle.jdbc.pool.OracleDataSource" /> 
    <property name="dataSourceProperties"> 
     <props> 
      <prop key="URL" value="${jdbc.url}" /> 
      <prop key="user" value="${jdbc.username}" /> 
      <prop key="password" value="${jdbc.password}" /> 
      <prop key="connectionCachingEnabled" value="true" /> 
     </props> 
    </property> 
</bean> 

注:還有一個漂亮的page上池大小(這實際上是從Oracle!)。

我也建議,清理你的代碼,刪除DbConnect類並注入(或創建)JdbcTemplate使用,而不是使用普通連接。保存管理所有JDBC對象。

private final JdbcTemplate jdbcTemplate; 

@Autowired 
public YourRepository(DataSource ds) { 
    this.jdbcTemplate=new JdbcTemplate(ds); 
} 

public List<User> getAllUsers() { 
    List<User> list = new ArrayList<>(); 
    return this.jdbcTemplate("select * from V_USERS t", new RowMapper() { 
     public User mapRow(ResultSet rs, int row) throws SQLException { 
      return RowFetcher.fetchUser(rs); 
     } 
    }); 
} 
+0

感謝您的完整解答。這非常有幫助,我將使用HikariCP和Spring JdbcTemplate。 – 0bj3ct

2

您可以設置dataSource限制屬性來控制緩存的大小。

<property name="connectionCacheProperties"> 
    <props> 
    <prop key="MinLimit">${jdbc.limit.min}</prop> 
    <prop key="MaxLimit">${jdbc.limit.max}</prop> 
    <prop key="InitialLimit">${jdbc.limit.init}</prop> 
    </props> 
</property> 
+0

這很可能是解決方案。 MaxLimit是默認的'0',它是無限的。 – KarlP

0

嘗試使用不同的數據源org.apache.commons.dbcp.BasicDataSource

1

我們有通用連接池(UCP),它是Java連接池。
有關更多配置詳細信息,請參閱UCP with Spring