`
jinnianshilongnian
  • 浏览: 21504170 次
  • 性别: Icon_minigender_1
博客专栏
5c8dac6a-21dc-3466-8abb-057664ab39c7
跟我学spring3
浏览量:2418704
D659df3e-4ad7-3b12-8b9a-1e94abd75ac3
Spring杂谈
浏览量:3008810
43989fe4-8b6b-3109-aaec-379d27dd4090
跟开涛学SpringMVC...
浏览量:5639502
1df97887-a9e1-3328-b6da-091f51f886a1
Servlet3.1规范翻...
浏览量:259925
4f347843-a078-36c1-977f-797c7fc123fc
springmvc杂谈
浏览量:1597331
22722232-95c1-34f2-b8e1-d059493d3d98
hibernate杂谈
浏览量:250226
45b32b6f-7468-3077-be40-00a5853c9a48
跟我学Shiro
浏览量:5858967
Group-logo
跟我学Nginx+Lua开...
浏览量:702014
5041f67a-12b2-30ba-814d-b55f466529d5
亿级流量网站架构核心技术
浏览量:785226
社区版块
存档分类
最新评论

dbcp配置及jdbc超时设置总结

阅读更多

 

14年618前夕的某个晚上的如下sql:

<!--添加同步数据-->
<insert id="insert" parameterClass="order">
  INSERT INTO aa(ID,ORDERID,CREATEDATE)
  VALUES
  (seq.Nextval,#orderId#,#createDate#)
  <selectKey resultClass="java.lang.Long">
    SELECT seq.CURRVAL FROM DUAL
  </selectKey>
</insert>

会抛出800多条如下错误

Caused by: java.sql.SQLException: ORA-01013: 用户请求取消当前的操作
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:745)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:219)
at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:970)

 

原因是sql执行时间太长,jdbc驱动主动去取消了操作。

 

建议:

1、看一下该sql的平均执行时间,对该sql设置一个超时时间。(执行时间太长会对占用着连接,造成其他人拿不到连接)

2、找DBA咨询下有没有办法优化下该sql,比如能不能并行插入。或者能不能做分区。

 

 

1、数据源配置

如果使用apache dbcp时,且可能遇到连接数瓶颈时,可以调整如下配置:

 

<!—建议以下值尽量一样,没必要频繁的过期空闲连接(除非比如连接池资源紧缺,可以考虑) -->
<property name="maxIdle" value="80" />
<property name="minIdle" value="80" />
<property name="initialSize" value="80"/>
<property name="maxActive" value="80" />

 

<!—这个是等待获取连接池连接时间,也不要太大,比如设置在500毫秒 -->
<property name="maxWait" value="500" />

<!-- 移除无引用连接(那些没有close的连接)此处设置为false,需要保证程序中连接一定释放 -->

<property name="removeAbandoned" value="false"></property>
<property name="removeAbandonedTimeout" value="300000"></property>
<!-- 一个连接空闲多久从池中移除,此处不做判断-->
<property name="minEvictableIdleTimeMillis" value="-1" />
<!-- 过期时循环测试多少次(0 就相当于关闭定时器) -->
<property name="numTestsPerEvictionRun" value="0" />
<!-- expire connection 定时器周期 -->
<property name="timeBetweenEvictionRunsMillis" value="120000" />

<!-- 当连接空闲时是否测试,即保持连接一直存活,配合expire connection 定时器使用 -->

<property name="testWhileIdle" value="false"></property>

 

如果是mysql库,可能存在8小时问题,可以考虑开启过期定时器(numTestsPerEvictionRun=1),定期过期一下连接,timeBetweenEvictionRunsMillis时间可以设置在8小时左右.

 

另外可以通过如下配置来配置socket连接/读超时:

<property name="connectionProperties"

value="oracle.net.CONNECT_TIMEOUT=2000;oracle.jdbc.ReadTimeout=2000"></property>

(此处的连接和读取超时时间,请根据自己业务来考虑大小)

 

具体配置请参考:http://www.importnew.com/2466.html

 

2、ibatis配置

**项目使用的是ibatis-sqlmap-2.3.4.726.jar版本,而从2.3.1起:

o Removed maxTransactions, maxRequests, maxSessions from configuration, all are now controlled by the resource providers。(即已经移除了maxTransactions, maxRequests, maxSessions配置)

  

因此我们只需要如下配置:

<settings cacheModelsEnabled="false" enhancementEnabled="true"

lazyLoadingEnabled="false" errorTracingEnabled="true" maxRequests="32"

defaultStatementTimeout="2"/>

 

defaultStatementTimeout单位是秒;根据业务配置。

  

如果想只设置某个Statement的超时时间,可以考虑:<insert ……timeout="2">

 

之前线上报如下错误,原因就是statement执行超时了。

Cause:java.sql.SQLException:ORA-01013:用户请求取消当前的操作

 

3、spring事务管理器配置

提供全局的事务级别的超时时间:

<bean id="oracleTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

  <property name="dataSource" ref="oracleDataSource" />

  <property name="defaultTimeout" value="2"/>

</bean>

 

总结:

超时设置主要有以下几个:

1、连接超时

2、读数据超时

3、Statement超时

4、事务级别的超时=N* Statement超时 + GC 暂停time

 

之前总结过事务超时的一些问题,有兴趣可以参考下:

http://jinnianshilongnian.iteye.com/blog/1986023

http://www.importnew.com/2466.html

 

另一个数据库连接池需要注意的点:
<bean id="msqlDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
如果没有加destroy-method ,而且重启次数太频繁,造成重启tomcat 旧的数据库连接池的连接不释放,这样会有好多数据库连接占着一段时间不释放;所以最好加上destroy-method。
//////////////////////乱七八糟////////////////////////////////////////////////////////////////////////////////////////////////////////////
当超过最大的连接数目的时候,会删除连接。
if (config != null && config.getRemoveAbandoned() && (getNumIdle() < 2) && (getNumActive() > getMaxActive() - 3) ) {
  removeAbandoned();
}
这段代码的作用是失效孤儿连接,即有人拿到连接但是没有close的。 
 
1、网络阻塞/不稳定时的级联效应(比如我现在写的ssdb-client 在网络出现故障(网络不可用)时 我会设置一个时间,在这个时间内的请求全部tiemout)
连接池内部应该根据当前网络的状态(比如超时次数太多),对于一定时间内的(如100ms)全部timeout,根本不进行await(maxWait)。
还有一个就是当前等待连接池的人数,比如现在等待1000个,那么接下来的等待是没有意义的,这样还会造成滚雪球(ssdb-client采用了这种策略)。
2、等待超时应该尽可能小点(除非很必要),即使返回错误页,也比等待强。
dbcp的比较容易出问题的地就是 设置的超时时间太长,造成大量的TIMED_WAIT,线程阻塞,而且是滚雪球,一旦出问题很难立即回复,而且这个可以通过[1]说的解决。 
 
大部分数据库client都会有一个取消statement执行的功能(即假设我们设置QueryTimeout=2秒,如果2秒内没返回信息,那么有个任务会主动发送一个取消的sql去取消当前statement的执行)
1、mysql每个连接会创建一个Timer(每个Timer会创建一个Thread)
2、每创建一个Statement会提交一个TimerTask(每个Task在执行时会创建一个Thread)
也就是说假设我们500个连接池,每个连接执行1个statement,最坏的情况下会创建:
500*1+500*1=1000个线程。
假设一个应用中有三个mysql库,那么最坏情况下有:
1000*3=3000个线程创建。
如果我们数据库采用了分库分表或者读写分离,可想而知。在压力大的时候。
假设os对线程释放不是特别快的话,cancel掉的线程可能并不是立即可用(我不确定,熟悉的同学可解释下)。
 
而oracle采用不同的策略:
1、每个ClassLoader一个watchdog 线程(类似于mysql的timer);
2、每个Statement一个Task,而线程是在watchdog需要取消时去触发的,即watchdog发现该Statement需要cancel时,调用其某个方法,该方法快速创建线程并运行;
也就是说假设我们500个连接池,每个连接执行1个statement,最坏的情况下会创建:
1+500*1=501个线程。
假设一个应用中有三个mysql库,那么最坏情况下有:
1 + 500*3=1501个线程创建。
解决方案:
1、最好的方案是改mysql实现。
2、修改底层系统支持的线程数。
//////////////////////乱七八糟////////////////////////////////////////////////////////////////////////////////////////////////////////////

 

另外dbcp 1.x使用的是commons-pool 1.x,高并发下性能不是很好;考虑升级2.x或者如果新项目可以考虑使用druid或proxool,老项目还是慎重迁移(之前我迁移过是没有问题的,不过还是慎重)。
 
2
0
分享到:
评论
2 楼 a814902893 2017-11-06  
timeBetweenEvictionRunsMillis表示空闲连接回收器的运行周期,值为负数表示不开启;minEvictableIdleTimeMillis表示回收器的线程数,默认为3;数据库的连接超时问题应该设置minEvictableIdleTimeMillis的值.
1 楼 huangzhiqiu1989 2016-09-12  
曾经遇到一个问题,spring jdbc在批量更新数据的时候,数据量过大,导致出现java.sql.SQLException:关闭的连接,不知道楼主有什么好的解决方案?

相关推荐

    dbcp.rar_Commons-jdbc.zip jar_DBCP_commons jdbc_dbcp jar_dbcp.ja

    总结一下,这个压缩包可能包含的是Apache Commons DBCP的组件和依赖,用于搭建和使用JDBC连接池。在实际开发中,DBCP可以帮助我们高效地管理和复用数据库连接,减少数据库操作的开销,提升应用程序的性能。使用DBCP...

    JDBC与DBCP连接mysql工程

    总结,"JdbcDbcp"这个压缩包很可能包含了使用JDBC和DBCP连接MySQL数据库的示例代码。通过学习这些代码,你可以理解如何在实际项目中设置和使用数据库连接池,以及如何有效地管理数据库连接,从而提高应用的性能和...

    jdbc与dbcp数据库连接

    3. **管理便捷**:DBCP提供了配置参数,如最大连接数、超时时间等,便于管理数据库连接。 4. **线程安全**:连接池保证了多线程环境下的安全性。 **DBCP使用步骤** 1. **引入依赖**:在项目中添加DBCP的jar包依赖...

    揭秘JDBC超时机制完整版

    DBCP提供了获取连接的超时设置,但这与JDBC的timeout机制分离。当通过DBCP的getConnection()方法请求连接时,可以设置超时,但这只影响获取连接的过程,而不是数据库操作的超时。 Transaction Timeout通常在框架...

    JDBC (c3p0、dbcp、jndi及不使用连接池)代码

    总结来说,Java连接数据库的方式多样,从基础的JDBC直接操作到使用连接池技术,如c3p0和dbcp,以及通过JNDI在应用服务器中管理数据源。根据项目需求和环境选择合适的方法,能有效提升数据库操作的效率和应用程序的...

    jdbc连接池dbcp工具包

    总的来说,DBCP作为一款成熟的JDBC连接池实现,提供了丰富的配置选项和良好的性能,适用于各种Java Web应用。但是,随着技术的发展,像HikariCP、C3P0等新型连接池的出现,它们在性能和稳定性上可能更具优势,开发者...

    org.apache.commons.dbcp.BasicDataSource的解决方法

    2. **空闲超时设置** - 使用`timeBetweenEvictionRunsMillis`和`minEvictableIdleTimeMillis`设置连接空闲检查和回收策略,避免长时间未使用的连接占用资源。 3. **验证测试** - 设置`testOnBorrow`和`testOnReturn`...

    commons DBCP 配置参数简要说明

    - 配置文件中提到的其他参数如`jdbc.driverClassName`、`jdbc.url`等是数据库连接的基本配置,必须正确设置以确保能够成功连接数据库。 通过以上介绍,我们可以了解到Commons DBCP配置参数的具体含义及其作用,有助...

    DBCP配置数据库连接池

    在实际应用中,为了保证系统的稳定性和安全性,还需要考虑更多的细节,比如异常处理、事务管理、连接超时设置、连接验证策略等。同时,由于DBCP的版本较旧,现在更推荐使用如HikariCP、Druid等性能更好、更稳定的...

    配置DBCP数据源的Jar包

    2. **Commons-DBCP**:Apache Commons DBCP是Apache Commons项目的一部分,它提供了一个实现JDBC连接池的类库。DBCP包含了对数据库连接的创建、管理和维护等功能。 3. **Commons-Pool**:这是Apache Commons的另一...

    DBCP,C3P0,Tomcat_JDBC 性能及稳定性测试代码

    本项目提供了对三种常用的Java数据库连接池——DBCP(BasicDataSource)、C3P0和Tomcat JDBC的性能及稳定性测试代码。下面将详细介绍这三个连接池的工作原理、特性以及如何进行性能测试。 1. **DBCP ...

    Tongweb5中配置JDBC连接池

    选择合适的连接池,并配置相应的参数,如最大连接数、最小连接数、超时时间等。例如,如果使用C3P0,可以在`context.xml`中添加以下配置: ```xml &lt;Resource name="jdbc/MyDB" auth="Container" type=...

    DBCP配置数据库连接池需要的jar包

    DBCP连接池提供了许多可配置的参数用于性能优化,比如调整连接的最大和最小数量,设置超时时间,以及是否在借用连接时进行验证查询等。合理配置这些参数可以确保系统在高并发下运行稳定,并且有效地利用系统资源。 ...

    tomcat5.5 的dbcp配置

    - `maxActive`、`maxIdle`、`maxWait`:分别表示最大活动连接数、最大空闲连接数及等待超时时间。 3. **添加ResourceLink**:在`webapps/myapp/META-INF/context.xml`文件中添加ResourceLink元素,以将全局资源...

    dbcp 1.2.2

    Apache Commons DBCP 1.2.2支持JDBC 3.0及更高版本,因此它可以与大部分主流的Java兼容数据库驱动一起使用。不过,由于这是较旧的版本,可能不包含某些新功能和改进,如JDBC 4.0的支持和内存泄漏防护。 总的来说,...

    dbcp tomcat 配置方法 代码

    在Tomcat这样的Servlet容器中配置DBCP,可以优化应用程序的性能,减少由于创建和销毁数据库连接而产生的开销。以下是一个详细的DBCP在Tomcat中的配置方法。 首先,我们需要了解数据库连接池的基本概念。数据库连接...

    DBCP连接池DBCP和C3P0配置

    ### DBCP与C3P0连接池配置详解 #### 一、DBCP与C3P0概述 在Java开发中,数据库连接池是提高应用性能的重要手段之一。通过复用预分配好的数据库连接资源,避免了频繁创建和销毁数据库连接所带来的性能开销。Apache ...

    commons-dbcp.jar.rar

    `BasicDataSource`是数据源的实现,它提供了配置连接池的接口,如最大连接数、最小连接数、超时时间等。`PoolableConnection`则是池中实际的数据库连接,它封装了JDBC的`Connection`对象,增加了连接的管理和监控...

    jdbc用到的jar包(commons-collections-3.1.jar、commons-dbcp-1.2.2.jar、commons-pool.jar)

    DBCP包括了数据库连接池的基本实现,如`BasicDataSource`,它支持配置最大连接数、超时设置、验证查询等特性。 3. **Apache Commons Pool** (`commons-pool.jar`): 这是另一个Apache Commons项目,它是通用对象池...

    dbcp连接池jar包和配置文件

    - 连接超时设置:合理设置连接超时,避免因长时间未使用的连接占用资源。 6. **其他连接池组件对比** - DBCP与其他连接池组件(如C3P0、HikariCP、Druid)相比,可能在性能和稳定性上稍逊一筹,但其简单易用的...

Global site tag (gtag.js) - Google Analytics