项目中数据库超时设置整理

1.背景

友好的超时设置能防止网络问题或者不友好的查询(主要是慢查询)对数据库连接池的伤害,比如慢查询占用过多连接导致正常业务逻辑无数据库连接可用。
所以我们需要捋一捋项目中设计到的可以设置超时时间的地方,首先看下应用于数据库之间timeout的层级关系。大体层级从下往上依次是OS SocketTimeout->JDBC Socket Timeout–>Statement Timeout->Transation Timeout。

 


“Statement Timeout无法处理网络连接失败时的超时,它能做的仅仅是限制Statement的操作时间。网络连接失败时的timeout必须交由JDBC来处理。 JDBC的Socket Timeout会受到操作系统Socket Timeout设置的影响。 ”

DBCP连接池位于图2的左侧,你会发现timeout层级与DBCP是相互独立的。DBCP负责的是数据库连接的创建和管理,并不干涉timeout的处理。当连接在DBCP中创建,或是DBCP发送校验query检查连接有效性的时候,socket timeout将会影响这些过程,但并不直接对应用造成影响。 
当在应用中调用DBCP的getConnection()方法时,你可以设置获取数据库连接的超时时间,但是这和JDBC的timeout毫不相关。 ”
以上两段文字引自图片来源网址。

2. 各个层级设置

2.1 JDBC Socket Timeout

一般大家在项目中设置JDBC_URL都是类似这样:

jdbc:mysql://localhost:3306/db?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&autoReconnectForPools=true&connectTimeout=1000&socketTimeout=3000

其中socketTimeout即为配置的JDBC Socket Timeout。其中connectTimeout为JDBC建立连接的超时时间。connectTimeout和socketTimeout的默认值为0时,即timeout不生效。

2.2 Statement Timeout

顾名思义,Statement Timeout即是用来设置Statement执行时长的。笔者使用Mybatis,可以在配置文件中设置defaultStatementTimeout来配置一个全局Statement Timeout。当然对于某一Statement语句,也可以单独配置,如下所示:

@Options(timeout = 15)

使用注解@Options在Statement语句的方法上。

2.3 Transation Timeout

“简单地说,Transaction Timeout就是“Statement Timeout * N(需要执行的statement数量) + @(垃圾回收等其他时间)”。Transaction timeout用来限制执行Statement的总时长。”
项目中配置transactionManager时可以设置Transaction Timeout,即设置AbstractPlatformTransactionManager的属性值defaultTimeout,默认是-1。
也可以使用另外的配置文件设置单独的Transaction Timeout:

<tx:attributes> 
<tx:method name=“…” timeout=“3″/> 
</tx:attributes>

当然比较方便的还是使用注解,设置注解@Transactional中的timeout属性即可。

3. 总结

所以想规避网络错误,设置JDBC Socket Timeout,想控制某一Statement的执行时间防止慢查询时配置Statement Timeout,我的建议是以上全部主动设置默认超时时间,如有特殊,可单独设置Statement Timeout和Transaction Timeout。

4. 参考链接

1.http://www.importnew.com/2466.html
2.http://elf8848.iteye.com/blog/1931778

posted @ 2016-02-03 21:21  liubey的自言自语  阅读(671)  评论(0编辑  收藏  举报