Transaction Timeout
对数据做批量操作的时候,执行数据提交的时间做限制,超出所设置的timeout值将抛出异常。
举例:我批量提交10000条数据,需要30秒,而我设置的Transaction timeout是4秒,就会抛对应异常
Statement Timeout
statement timeout用来限制语句查询执行时长timeout的值通过调用JDBC的java.sql.Statement.setQueryTimeout(in timeout)API进行设置。不过现在开发者已经很少直接在代码中设置,而多是通过框架来进行设置。
举例:我查一个sql,如果要查询30秒,我查询Statement timeout设置的是2秒,则抛出对应异常。
Statementvoid setQueryTimeout(int seconds) throws SQLException;
connect timeout和socket timeout
一次完整的请求包括三个阶段:1、建立连接 2、数据传输 3、断开连接
connect timeout:如果与服务器(这里指数据库)请求建立连接的时间超过ConnectionTimeOut,就会抛 ConnectionTimeOutException,即服务器连接超时,没有在规定的时间内建立连接。
Connectionvoid setNetworkTimeout(Executor executor, int milliseconds) throws SQLException;
socket timeout:如果与服务器连接成功,就开始数据传输了。如果服务器处理数据用时过长,超过了SocketTimeOut,就会抛出SocketTimeOutExceptin,即服务器响应超时,服务器没有在规定的时间内返回给客户端数据。
下面展示了socket timeout的两个设置项,不同的JDBC
socket连接时的timeout:通过Socket.connect(SocketAddress endpoint, int timeout)设置
socket读写时的timeout:通过Socket.setSoTimeout(int timeout)设置
操作系统的socket timeout配置
通常,应用会在调用Socket。read()由于网络问题被阻塞住,而很少在调用Socket。write()进入waiting状态,这取决于网络构成和错误类型。当Socket。write()被调用时,数据被写入到操作系统内核的缓冲区,控制权立即回到应用手上。因此,一旦数据被写入内核缓冲区,Socket。write()调用就必然会成功。但是,如果系统内核缓冲区由于某种网络错误而满了的话,Socket。write()也会进入waiting状态。这种情况下,操作系统会尝试重新发包,当达到重试的时间限制时,将产生系统错误。
常见数据源设置超时时间
JDBC Driver | connectTimeout配置项 | socketTimeout配置项 | url格式 |
MySQL Driver | connectTimeout(默认值:0,单位:ms) | socketTimeout(默认值:0,单位:ms) | jdbc:mysql://[host:port],[host:port]…/[database][?propertyName1][=propertyValue1][&propertyName2][=propertyValue2] |
MS-SQL Driver | loginTimeout(默认值:0,单位:s) | socketTimeout(默认值:0,单位:s) | jdbc:sqlserver://[:][/][;=[;…]] |
Postgresql Driver | loginTimeout(默认值:0,单位:s) | socketTimeout(默认值:0,单位:s) | jdbc:postgresql://host:port/database[?propertyName1][=propertyValue1][&propertyName2][=propertyValue2] |
Oracle Thin Driver | oracle.net.CONNECT_TIMEOUT (默认值:0,单位:ms) | oracle.jdbc.ReadTimeout(默认值:0,单位:ms) | 不支持通过url配置,只能通过OracleDatasource.setConnectionProperties() API设置,使用DBCP时可以调用BasicDatasource.setConnectionProperties()或BasicDatasource.addConnectionProperties()进行设置 |
灵活的使用socketTimeout
总结
1.socket timeout的值必须要高于statement timeout,否则,socket timeout将会先生效,这样statement timeout就变得毫无意义,也无法生效。
2.当数据库出现宕机或网络异常时,jdbc 驱动的 socket 超时是必须的。由于TPC/IP 的结构,socket 没有办法检测到网络错误,因此应用也不能检测到与数据库之间的连接是否已经断开。如果没有设置 socket 超时,应用程序会一直等待数据库返回结果。为了避免死连接,socket 必须设置超时时间,通过设置超时时间可以防止出现网络错误时一直等待的情况并缩短故障时间。一般的数据库连接池都会提供链接检查的功能,但对于已经在使用中的连接往往不会再进行检。
MYSQL建议配置设置
1. JDBC超时设置
connectTimeout:表示等待和MySQL数据库建立socket链接的超时时间,默认值0,表示不设置超时,单位毫秒,建议30000
socketTimeout:表示客户端和MySQL数据库建立socket后,读写socket时的等待的超时时间,linux系统默认的socketTimeout为30分钟,可以不设置
2. 连接池超时设置
maxWait:表示从数据库连接池取链接,连接池没有可用连接时的等待时间,默认值0,表示无限等待,单位毫秒,建议60000
3. MyBatis查询超时
defaultStatementTimeout:表示在MyBatis配置文件中默认查询超时间,单位秒,不设置则无线等待
如果一些sql需要执行超过defaultStatementTimeout可以通过Mapper文件单独的sql的timeout进行配置
4. 事务超时
事务超时用于控制事务执行的超时,执行时间是事务内所有代码执行总和,单位为秒。
学习资料来源:
https://www.iteye.com/blog/san-yun-1894722
https://www.cnblogs.com/alchemystar/p/13084012.html
http://www.safebase.cn/article-224817-1.html