序
本文主要介绍下jdbc的socket timeout的设置
jdbc timeout类别
主要有如下几个类别
transaction timeout
设置的是一个事务的执行时间,里头可能包含多个statement
statement timeout()
设置的是一个statement的执行超时时间,即driver等待statement执行完成,接收到数据的超时时间()
jdbc socket timeout
设置的是jdbc I/O socket read and write operations的超时时间,防止因网络问题或数据库问题,导致driver一直阻塞等待。()
os socket timeout
这个是操作系统级别的socket设置()。
上面的不同级别的timeout越往下优先级越高,也就是说如果下面的配置比上面的配置值小的话,则会优先触发timeout,那么相当于上面的配置值就”失效”了。
jdbc socket timeout
这个不同数据的jdbc driver实现不一样
mysql
通过url参数传递即可
pg
pg也是通过url传递,不过它的单位与mysql不同,mysql是毫秒,而pg是秒
oracle
oracle需要通过oracle.jdbc.ReadTimeout参数来设置,连接超时参数是oracle.net.CONNECT_TIMEOUT
oracle.jdbc.ReadTimeout
driver内部将该值设置到oracle.net.READ_TIMEOUT变量上
可用看到最后设置的是socket的soTimeout
实例
超时错误输出
刚开始会有数据输出,但是到了某个resultSet的next的时候,报了超时(),这个超时指定的是当result.next方法触发新的一批数据的拉取()之后在timeout时间返回内没有收到数据库返回的数据。
oracle的jdbc默认的fetchSize为10,也就是每个fetch,如果超过指定时间没接收到数据,则抛出timeout异常。
小结
jdbc的socketTimeout值的设置要非常小心,不同数据库的jdbc driver设置不一样,特别是使用不同连接池的话,设置也可能不尽相同。对于严重依赖数据库操作的服务来说,非常有必要设置这个值,否则万一网络或数据库异常,会导致服务线程一直阻塞在java.net.SocketInputStream.socketRead0。
如果查询数据多,则会导致该线程持有的data list不能释放,相当于内存泄露,最后导致OOM
如果请求数据库操作很多且阻塞住了,会导致服务器可用的woker线程变少,严重则会导致服务不可用,nginx报504 Gateway Timeout
doc
oracle.jdbc.ReadTimeout
深入理解JDBC的超时设置
在Spring中基于JDBC进行数据访问时如何控制超时
BugFix-HttpURLConnection
领取专属 10元无门槛券
私享最新 技术干货