JDBC
四种连接方式
- JDBC-ODBC bridge
- Native-API driver
- Network-Protocol driver (Middleware driver)
- Database-Protocol driver (Pure Java driver) or thin driver.
socket通信应用与数据库间的timeout层级

JDBC的socket timeout会受到操作系统socket timeout设置的影响

什么是Transaction Timeout?
transaction timeout一般存在于框架(Spring, EJB)或应用级。transaction timeout就是“statement Timeout * N(需要执行的statement数量) + @(垃圾回收等其他时间)”。transaction timeout用来限制执行statement的总时长。
可以使用XML或使用@Transactional注解来进行设置。
Spring中,数据库连接被保存在ThreadLocal里,这被称为事务同步(Transaction Synchronization),与此同时,事务的开始时间和消耗时间也被保存下来。当使用这种代理连接创建statement时,就会校验事务的消耗时间。
Spring事务超时 = 事务开始时到最后一个Statement创建时时间 + 最后一个Statement的执行时超时时间(即其queryTimeout)
不要忽略应用中如远程调用产生的事务时间和这个事务时间是否对您的事务产生影响
什么是Statement Timeout?
statement timeout用来限制statement的执行时长,timeout的值通过调用JDBC的java.sql.Statement.setQueryTimeout(int timeout) API进行设置。
以iBatis为例,statement timeout的默认值可以通过sql-map-config.xml中的defaultStatementTimeout 属性进行设置。同时,你还可以设置sqlmap中select,insert,update标签的timeout属性,从而对不同sql语句的超时时间进行独立的配置。
MySQL JDBC Statement的QueryTimeout处理过程
1. 通过调用Connection的createStatement()方法创建statement
2. 调用Statement的executeQuery()方法
3. statement通过自身connection将query发送给MySQL数据库
4. statement创建一个新的timeout-execution线程用于超时处理
5. 5.1版本后改为每个connection分配一个timeout-execution线程
6. 向timeout-execution线程进行注册
7. 达到超时时间
6. TimerThread调用JtdsStatement实例中的TsdCore.cancel()方法
7. timeout-execution线程创建一个和statement配置相同的connection
8. 使用新创建的connection向超时query发送cancel query(KILL QUERY “connectionId”)

什么是JDBC的socket timeout?
第4种类型的JDBC使用socket与数据库连接,数据库并不对应用与数据库间的连接超时进行处理。
JDBC的socket timeout在数据库被突然停掉或是发生网络错误(由于设备故障等原因)时十分重要。由于TCP/IP的结构原因,socket没有办法探测到网络错误,因此应用也无法主动发现数据库连接断开。如果没有设置socket timeout的话,应用在数据库返回结果前会无期限地等下去,这种连接被称为dead connection。
为了避免dead connections,socket必须要有超时配置。socket timeout可以通过JDBC设置,socket timeout能够避免应用在发生网络错误时产生无休止等待的情况,缩短服务失效的时间。
不推荐使用socket timeout来限制statement的执行时长,因此socket timeout的值必须要高于statement timeout,否则,socket timeout将会先生效,这样statement timeout就变得毫无意义,也无法生效。
下面展示了socket timeout的两个设置项,不同的JDBC驱动其配置方式会有所不同。
socket连接时的timeout:通过Socket.connect(SocketAddress endpoint, int timeout)设置
socket读写时的timeout:通过Socket.setSoTimeout(int timeout)设置

浙公网安备 33010602011771号