2015-02-12 71 views
1

问:与数据库的活动没有结束的物理连接的地块即使连接池。有人能告诉我为什么这样吗?Oracle数据源连接池不工作使用Spring和JdbcTemplate的

我使用oracle.jdbc.pool.OracleDataSource配置的连接池设置。但是看起来物理连接在使用后没有关闭。 我想,既然是连接池,连接将从池中被重用,那么这么多的物理连接将无法进行, 但那不是什么现在发生的事情!

有从应用[不从PLSQL显影剂或任何这样的客户端工具], 由于它而试图做数据库写操作序幕TNS错误, 其中在数据库中生成100+活性的物理连接因为即使有大量的活动连接,读取操作也可以。

这里是Spring配置,

<bean id="oracleDataSource" class="oracle.jdbc.pool.OracleDataSource" destroy-method="close" 
           p:URL="${url}" 
           p:user="${username}" 
           p:password="${password}" 
           p:connectionCachingEnabled="true"> 
           <property name="connectionProperties"> 
            <props merge="default"> 
             <prop key="AutoCommit">false</prop> 
            </props> 
           </property> 
</bean> 

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" 
           p:dataSource-ref="oracleDataSource" /> 

<bean id="transactionManager" 
           class="org.springframework.jdbc.datasource.DataSourceTransactionManager" 
           p:dataSource-ref="oracleDataSource"> 
</bean> 

返回的100多个活动连接的SQL是,

select username, terminal,schemaname, osuser,program from v$session where username = 'grduser' 

回答

1

您应该配置连接高速缓存,最大连接的隐式连接的缺省值缓存是为数据库配置的最大数据库会话数。

+0

感谢您提及默认值+1。让我详细了解它并缓存 – spiderman 2015-02-12 03:13:44

+0

我已经发布了详细的解决方案 – spiderman 2015-02-18 16:44:11

0

感谢@Evgeniy Dorofeev。

方案中,详细:

  1. 的connectionCache已启用,但性质没有设置。如下书面 设置属性,

`

<bean id="oracleDataSource" class="oracle.jdbc.pool.OracleDataSource" destroy-method="close" 
             p:URL="${url}" 
             p:user="${username}" 
             p:password="${password}" 
             p:connectionCachingEnabled="true"> 
             <property name="connectionProperties"> 
              <props merge="default"> 
               <prop key="AutoCommit">false</prop> 
              </props> 
             </property> 
     <property name="connectionCacheProperties"> 
        <props> 
         <prop key="MinLimit">5</prop> 
         <prop key="MaxLimit">10</prop> 
         <prop key="InactivityTimeout">2</prop> 
        </props> 
       </property> 
    </bean> 

`

现在,在需要连接的应用程序的所有操作,它会尝试从如有池中获得并准备使用,但可以保证数据库最多只能有10个活动的物理连接。任何尝试获得额外的物理连接都会导致应用程序端发生数据库错误。

  • 即使您已设置的connectionCache,请确保您的应用程序没有明确地试图获得一个连接,像
  • Connection connection = getJdbcTemplate().getDataSource().getConnection();

    这是令人震惊的, JDBCTemplate不管理关闭此连接。因此,你必须自己使用后关闭,否则物理连接仍然会积极和未关闭即使在使用后。所以,下一次你再打电话这一点,试图得到一个新的物理连接,并保持未闭合,导致堆放活动连接达到MAXLIMIT直到。

    当您想要将其作为参数传递给某个其他函数时,可能需要明确的连接,比如在ArrayDescriptor的情况下[如果您与PLSQL交谈存储过程具有IN参数以接受值数组,一个Varchar数组或RAW数组]。如果你需要创建一个ArrayDescriptor,

    ArrayDescriptor arrayDescriptor = ArrayDescriptor.createDescriptor(
              "SOME_TYPE_NAME", connection); 
    ARRAY SQLArray= new ARRAY(arrayDescriptor, connection , arrayString); 
    

    因此做了connection.close()明确地在这里。

    附加信息:

    Connection connection = getJdbcTemplate().getDataSource().getConnection() 
    
    • 这试图建立与数据源,此DataSource对象所表示的连接。

    调用这行代码 - 一次,将尝试建立一个新的连接。 再次调用,将建立第二个连接。对于每个请求,它将创建一个新的连接!.So如果您的maxLimit是10, 直到数据库中有10个活动的物理连接,呼叫将会成功,但是 请注意,所有连接都处于活动状态[未关闭] 。

    因此,可以说,现在有10个活动数据库连接,如MAXLIMIT设置为10

    因此,任何请求,需要一个数据库操作,这将经历访问通过JdbcTemplate的连接的 正常路线将从[10个连接]中获取已建立的连接

    但是,任何调用此代码getJdbcTemplate().getDataSource().getConnection()访问连接 的请求都将尝试建立NEW连接,并且会失败,从而导致异常。

    解决此问题的唯一方法是在我们明确创建连接时显式关闭连接。 即调用connection.close() 当我们没有明确地创建连接,并且当它由Spring管理时,Spring将负责关闭连接 。在使用Oracle Data Source池和JDBCTemplate的情况下,关闭连接[将 连接返回到池]由Spring管理。