开发者社区> 小桥河西> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

关于数据库的SQL超时实现策略

简介: 在执行SQL的时候,有可能需要限制SQL的最长执行时间。这个限制在JDBC和.NET Data Provider中分别通过下面两个方法设置。 其他数据库驱动可能也有类似的参数。 Statement.setQueryTimeout() DbCommand.CommandTimeout() 这个功能是很简单的,但是如何实现这个超时呢?不同的数据库驱动,可能会采取不同的方法。
+关注继续查看
在执行SQL的时候,有可能需要限制SQL的最长执行时间。这个限制在JDBC和.NET Data Provider中分别通过下面两个方法设置。
其他数据库驱动可能也有类似的参数。
  • Statement.setQueryTimeout()
  • DbCommand.CommandTimeout()
这个功能是很简单的,但是如何实现这个超时呢?不同的数据库驱动,可能会采取不同的方法。我接触过几个驱动,大致有下面几种方法。

1)在客户端进行超时控制
客户端驱动通过设置Socket数据接受超时或者在另一个线程里开一个定时器进行超时判断。当检出SQL超时时取消正在执行的SQL。
使用这种方法的前提是服务端支持SQL取消功能。取消SQL的请求是不能直接用原来的连接往服务端发的,因为这个连接已经被这个正在执行的SQL占据了,所以驱动内部必须新开一个Socket。取消SQL有一种极端的情况,由于发出取消请求的时刻和取消请求真正被执行的时刻之间有个时间差。在这个时间差里,有可能你想取消的SQL已经执行完毕,并且对应的物理连接回池,然后有新的连接拿到这个物理连接之后开始执行新的SQL。于是诡异的事情发生了,一个正常的SQL被莫名其妙的取消了。我们就曾遇到过这么变态的bug。
PostgreSQL的JDBC驱动pgjdbc就是这么干的。印象中Oracle和MySQL好像也是这么干的。

2)在服务端进行超时控制
驱动把超时参数发给服务端,由服务端处理超时,并把超时错误反馈给客户端。

这种方法通常工作得很好,但无法应付服务端或者网络故障。当发生故障时,客户端可能会在那儿一直傻等。
印象中SQL Server好像是这么干的。

3)客户端和服务端同时进行超时控制
除此1和2外,还有一种组合的方案,这就是PostgreSQL的.NET驱动Npgsql的实现。这也是本人见到过的最好的方案。
Npgsql通过向服务端发送statement_timeout参数让服务端进行超时控制,同时为了防止出现故障又在驱动里设置了一个计时器。但这个计时器的超时时间比用户设置的多5秒,所以驱动中的计时器可以在服务端超时机制失效的5秒之后挺身而出。


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
+关注
小桥河西
半个PostgreSQL DBA,热衷于数据库及分布式技术。 - https://github.com/ChenHuajun - https://pan.baidu.com/s/1eRQsdAa
187
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载