深入源碼和內核,一篇文章徹底理解數據庫的各種超時參數
1 前言
在日常數據庫的使用過程中,我們經常會遇到各種超時,特別是在網絡不穩定和業務高并發的情況下。理解這些超時的背后原理和工作機制,以及不同數據庫下的超時參數和設置方式,無疑會對異常狀況下的問題排查大有裨益;通過合理配置這些超時參數,也可以減少各種異常情況下應用宕機恢復的時間,從而提高 RTO 和 RPO,滿足 SLA 的要求。
本片文章,我們就來一起學習下這些超時的相關知識。
2 數據庫的超時參數有哪些?
總體而言,數據庫的超時參數有以下幾種:
- 事務超時:transaction timeout;
- 查詢超時 query timeout,有時也被稱為語句超時 statement timeout;
- 連接超時 connectTimeout:有時也被稱為網絡超時 NetworkTimeout;
- 登錄超時 loginTimeout;
- TCP 套接字超時( TCP socket timeout);
除了以上幾個常見的數據庫超時參數,還需要注意,客戶端的JDBC應用程序和服務端的數據庫管理系統,在服務器上都有操作系統級別的基于 tcp keep-alive 的超時檢測和保活機制;如果操作系統支持,客戶端的JDBC應用程序和服務端的數據庫管理系統,甚至也可能配置套接字級別的基于 tcp keep-alive的超時檢測和保活機制。
3 事務超時的含義是什么?
事務超時,即 transaction timeout, 可以用來限制某個事務中所有 statement 語句的處理時間之和的最大值,簡單來說,事務超時時間 statement timeout = 語句超時時間 statement/query timeout * 事務中語句個數 + 其他耗時(如業務代碼處理時間,gc 垃圾回收時間等)
事務超時一般在應用框架中進行配置, 如 spring 中,可以使用注解 @Transactional 指定。
4 查詢超時的含義是什么?
查詢超時,即 query timeout,有時也被稱為語句超時 Statement timeout,可以用來限制某個 statement 語句(可以是增刪改查)的最大執行時間,若該 sql語句在該超時時間內還沒有返回執行結果,應用端的數據庫驅動程序就會拋出超時異常,并發送取消執行的信號給遠程的數據庫管理系統,由數據庫管理系統取消該語句的執行,其底層依賴健康的TCP連接。
- JDBC 提供了標準 API 來指定語句超時:java.sql.Statement.setQueryTimeout(int timeout);
- 不過在實際應用中,大多數開發者都不會通過代碼直接指定語句超時,而是使用框架提供的配置機制來指定語句超時;
- 比如 mybatis中,可以通過注解 @defaultStatementTimeout 指定默認的語句超時時間,并在具體的 SQL語句中通過注解 @timeout 覆蓋全局的默認值;
- 語句超時的默認值是0,即沒有超時時間,具體超時時間的配置,需要根據業務特征進行配置,并沒有統一的推薦值;
- 在使用 batch 機制時,該超時時間是適用于某個單獨的sql還是該批次所有sql之和,JDBC并沒有統一要求,由具體的數據庫驅動自行實現;
圖片
5 連接超時
連接超時,即 connectTimeout,有時也被稱為 網絡超時 NetworkTimeout,是驅動程序建立 JDBC 底層的 TCP 連接的超時時間。
- JDBC 標準 API 中定義了該超時時間的含義,如 java.sql.Connection#setNetworkTimeout:
圖片
6 登錄超時 loginTimeout 的含義是什么?
登錄超時,即 loginTimeout,是數據庫用戶成功登錄到數據庫服務器的超時時間,由于用戶登錄數據庫服務器時,底層包含了和數據庫服務器之間的 tcp 連接的建立,也包含了數據庫服務器對用戶的認證,所以一般而言,需要配置登錄超時 > 連接超時;
- JDBC 標準 API 中定義了登錄超時的含義,如java.sql.DriverManager#setLoginTimeout,javax.sql.CommonDataSource#setLoginTimeout;
圖片
圖片
7 TCP 套接字超時
由于應用程序通過 TCP 協議讀寫網絡數據包,都是通過 TCP/IP 協議棧的 socket api 進行的,所以常規的套接字超時 socket timeout 同樣適用于 JDBC 應用程序。雖然 TCP是面向連接的協議,但這里的連接是虛擬的,是動態的,也是不對等的,所以應用程序需要通過 socket timeout 來檢測和感知網絡層面 TCP 連接的異常,從而避免僵死連接造成的無限等待;(對這塊感興趣的朋友,可以關注筆者對 tcp/ip 協議棧,對 tcpdump/wireshark/packetdrill 工具的相關分享文章);
- 套接字連接建立后,對 socket 中數據的讀寫操作都是阻塞的(涉及到 CPU 用戶態和內核態的切換以及系統調用),套接字超時即是讀寫 socket 底層數據時的阻塞超時時間;
- 調用 Socket.write()對 socket 進行寫操作時,應用通過系統調用將數據傳給本地操作系統內核的緩沖區之后就可以立即返回(控制權立即回到應用上),通過網絡對底層數據進行遠程傳輸的操作是由操作系統進行的,所以一般應用代碼的 socket 寫操作很快就會返回,一般不會發生長時間的阻塞(當然如果系統內核緩沖區由于網絡故障滿了的話,Socket.write()也會進入waiting阻塞狀態,此時操作系統會嘗試重新發包,當達到重試的次數時就會產生系統異常錯誤);
- 調用 Socket.read() 對 socket 進行讀操作時,由于首先需要通過網絡將 socket 底層的遠程數據傳輸到本地,然后才能經由操作系統將底層數據返回給用戶態的應用程序,所以一般應用代碼的 socket 讀操作會消耗一段時間,可能會因為長時間的阻塞而發生超時異常;
- 在網絡連接發生異常或服務器異常崩潰宕機時,因為 TCP/IP 的工作機制, socket 無法檢測到底層網絡的異常,因此應用系統也就無法檢測到跟 DBMS 之間的 TCP 連接是否處于斷開狀態,所以應用端如果沒有配置套接字超時,應用就會無期限地等待 DMBS的返回結果(這種連接也被稱為死亡連接或僵尸連接 "dead connection.") ,為了避免這種僵尸連接,同樣需要配置套接字超時;
8 登錄超時,連接超時,TCP 套接字超時的區別與聯系
登錄超時,連接超時,常規的套接字超時,三者的區別與聯系如下:
- 登錄超時是高級別的數據庫服務層面的超時,而連接超時和套接字超時是低級別的 tcp socket 層面的超時;
- 由于用戶登錄數據庫服務器時,底層包含了 和數據庫服務器之間的 tcp 連接的建立,也包含了數據庫服務器對用戶的認證,所以一般需要配置登錄超時 > 連接超時;
- 登錄超時和連接超時 只影響客戶端和數據庫服務器之間的連接的初始建立,而套接字超時 會影響客戶端和服務器之間的連接的整個生命周期,包括初始連接的建立,也包括連接建立完畢后所有SQL語句的執行(有些SQL可能需要耗費較長時間),所以一般需要配置套接字超時 > 登錄超時,套接字超時 > 連接超時;
- 由于三者聯系緊密且都跟網絡性能密切相關,在實踐中,有些數據庫驅動和數據庫連接池,可能會只暴露三者中的部分參數供用戶配置并基于用戶配置的參數值自動推導配置其余的參數(比如 hive 會基于 loginTimeout 自動推導并配置 socketTimeout, 比如 hikari 會基于 connectionTimeout 自動推導并配置 LoginTimeout);
- The loginTimeout specifies how long the whole process of logging into the database is allowed to take. It governs the operation of connecting and authenticating to the dbms server, this involves establishing a TCP connection followed by one or more exchanges of packets for the handshake and authentication to the dbms server;
- The connectTimeout specifies how long to wait for a TCP network connection to get established, it governs the time needed to establish a TCP socket connection, and as establishing a TCP connection is part of establishing a database connection and doesn't guarantee a login, so loginTimeout >= connectTimeout;
- A connection timeout occurs only upon starting the TCP connection. This usually happens if the remote machine does not answer. If you get an ConnectException, possible reasons are: the server has been shut down, you used the wrong IP/DNS name, wrong port or the network connection to the server is down.
- A connection timeout is the maximum amount of time that the program is willing to wait to setup a connection to another process. You aren't getting or posting any application data at this point, just establishing the connection, itself.
- The socketTimeout specifies how long the client will wait for a response to a command from the server before throwing an error, it governs the time a socket can be blocked waiting to read from a socket, this involves all reads from the server, not just during connect, but also during subsequent interaction with the server (eg executing queries),so you may want to set it higher (eg for other operations that take a long time to get a response back) than you are willing to wait for the login to complete;
- A socket timeout is dedicated to monitor the continuous incoming data flow. If the data flow is interrupted for the specified time the connection is considered as stalled/broken. Of course this only works with connections where data is received all the time and there are no delays longer than the configured socket timeout.
- A socket timeout is the timeout when waiting for individual packets. It's a common misconception that a socket timeout is the timeout to receive the full response. So if you have a socket timeout of 1 second, and a response comprised of 3 IP packets, where each response packet takes 0.9 seconds to arrive, for a total response time of 2.7 seconds, then there will be no timeout.
- By setting socket timeout to 1000 (ms) this would require that every second new data is received (assuming that you read the data block wise and the block is large enough).If only the incoming stream stalls for more than a second you are running into a socket timeout.This is especially important when HTTP servers process a complex request that requires some time on server side before the HTTP response data is available. If you configure socket timeout to 10000 (10 seconds) but the HTTP server requires 15 seconds after receiving the HTTP request, then you will never get the response as after 10 seconds you will get an SocketTimeoutException (no data is transmitted between reception of the HTTP request until the HTTP response is ready).
- A socketTimeout can be used as both a brute force global query timeout and a method of detecting network problems;
- the loginTimeout and connectTimeout are related to establishing a connection, while socketTimeout is relevant for the whole database session;
- connectTimeout and socketTimeout are timeouts on low-level socket operations, while loginTimeout is on a high level - the database level;
- Generally, the application hangs from network issues when the application is calling Socket.read(). However, depending on the network composition or the error type, it can rarely be in waiting status while running Socket.write(). When the application calls Socket.write(), the data is recorded to the OS kernel buffer and then the right to control is returned to the application immediately. Thus, as long as a valid value is recorded to the kernel buffer, Socket.write() is always successful. However, if the OS kernel buffer is full due to a special network error, even Socket.write() can be put into waiting status;
9 查詢超時的工作機制是什么?
查詢超時在不同數據庫管理系統和不同驅動下,其工作機制略有不同,但其工作原理是相似的,即大都是通過一個獨立的線程來跟蹤語句的執行時間,在執行時間超過指定的超時時間時,應用端拋出超時的錯誤,并通過底層的數據庫連接發送取消執行的信號給遠程的數據庫管理系統,由數據庫管理系統取消該語句的執行。
比如 Oracle數據庫中,其查詢超時的工作機制大體如下:
- 創建待執行 statement:Creates a statement by calling Connection.createStatement();
- 觸發執行 statement:Calls Statement.executeQuery();
- 通過 statement 底層的連接將 statement 遠程傳輸給數據庫管理系統:The statement transmits the Query to Oracle DBMS by using its own connection.
- 注冊該 statement 到超時處理線程 OracleTimeoutPollingThread:The statement registers a statement to OracleTimeoutPollingThread (1 for each classloader) for timeout process.
圖片
- 執行時發生了超時:Timeout occurs.
- 超時處理線程調用方法取消語句的執行:OracleTimeoutPollingThread calls OracleStatement.cancel().
圖片
- 通過 statement 底層的連接,發送取消執行的信號給遠程的數據庫管理系統,以取消語句的執行:Sends a cancel message through the connection and cancels the query being executed.
圖片
再比如Mysql中,其查詢超時的工作機制大體如下:
- 創建待執行 statement: Creates a statement by calling Connection.createStatement().
- 觸發執行 statement:Calls Statement.executeQuery().
- 通過 statement 底層的連接遠程傳輸 statement 給數據庫管理系統:The statement transmits the Query to MySqlServer by using the internal connection.
- 為每個 statement 創建一個超時處理線程(在 5.1 版本中,更改為為每個連接創建一個超時處理線程):The statement creates a new timeout-execution thread for timeout process;(For version 5.1.x, it changes to assign 1 thread for each connection.)
- 向超時處理線程注冊超時處理邏輯:Registers the timeout execution to the thread.
- 執行時發生了超時:Timeout occurs.
- 超時處理線程創建到數據庫管理系統的連接:The timeout-execution thread creates a connection that has the same configurations as the statement.
- 超時處理線程通過底層的連接,發送取消執行的信號給遠程數據庫管理系統以取消語句的執行:Transmits the cancel Query (KILL QUERY "connectionId“) by using the connection.
圖片
10 查詢超時和 TCP套接字超時有何關系?
我們經常遇到開發同學抱怨,明明對某個SQL語句配置了查詢超時,但看起來查詢超時就是不生效,其實這種情況是因為底層的網絡出了問題,而查詢超時機制在網絡異常的狀況下是不生效的,其原因如下:
- 高層次的異常依賴于低層次的異常,只有在低層次的異常機制正常工作的前提下,高層次的異常機制才能正常工作,所以事務超時和查詢超時的正常工作,都依賴于套接字超時的正常運轉;
- 查詢超時不能用來解決網絡異常狀況下的超時問題,查詢超時僅僅只能用來限制某個語句的執行時間;
- 為應對網絡連接的異常或數據庫管理系統的異常宕機,需要使用數據庫驅動的套接字超時;
- 一般不推薦通過套接字超時限制sql語句的執行時間,套接字超時一般需要配置為比查詢超時大一些 (如果套接字超時小于查詢超時,此時由于先觸發套接字超時的處理,查詢超時的處理邏輯也就不會被執行了,查詢超時也就失去了意義);
- The higher level timeout is dependent on the lower level timeout. The higher level timeout will operate normally only if the lower level timeout operates normally as well. If the JDBC driver socket timeout does not work properly, then higher level timeouts such as statement timeout and transaction timeout will not work properly either.
- The statement timeout does not handle the timeouts at the time of network failure, it does only one thing: restricts the operation time of 1 statement,and handling timeout to prevent network failure must be done by JDBC Driver;
- Socket timeout value for JDBC driver is necessary when the DBMS is terminated abruptly or an network error has occured (equipment malfunction, etc.).
- Because of the structure of TCP/IP, there are no means for the socket to detect network errors. Therefore, the application cannot detect any disconnection with the DBMS. If the socket timeout is not configured, then the application may wait for the results from the DBMS indefinitely. (This connection is also called a "dead connection."),to prevent dead connections, a timeout must be configured for the socket.
- Socket timeout can be configured via JDBC driver. By setting up the socket timeout, you can prevent the infinite waiting situation when there is a network error and shorten the failure time.
- It is not recommended to use the socket timeout value to limit the statement execution time. So the socket timeout value must be higher than the statement timeout value.
- If the socket timeout value is smaller than the statement timeout value, as the socket timeout will be executed first, and the statement timeout value becomes meaningless and will not be executed.
11 如何配置常見數據庫的 TCP 套接字超時?
- 如上文所說,為應對網絡連接的異常以及數據庫管理系統的崩潰宕機,需要配置數據庫驅動的套接字超時;
- 套接字超時在底層又分為創建連接的超時和讀寫數據的超時兩種,究其原因,是由 TCP 的工作機制決定的,包括連接建立的機制以及連接建立完畢后數據傳輸的機制;
- 套接字的連接超時和讀寫超時,在JAVA源碼層面,分別對應方法 Socket.connect(SocketAddress endpoint, int timeout) 和方法 Socket.setSoTimeout(int timeout):
圖片
圖片
- 絕大多數數據庫驅動都支持對上述兩種超時的配置,雖然不同數據庫驅動具體的配置方式略有不同,但在驅動代碼的最底層都是調用的方法 Socket.connect(SocketAddress endpoint, int timeout) 和方法 Socket.setSoTimeout(int timeout);
下面總結下常見數據庫中,套接字連接超時和讀寫超時的配置方式:
- mysql 可以通過url參數指定套接字的連接超時和讀寫超時,超時單位是毫秒,如:jdbc:mysql://localhost:3306/ag_admin?useUnicode=true&characterEncoding=UTF8&cnotallow=60000&socketTimeout=60000
- pg 也可以通過url參數指定套接字的連接超時和讀寫超時,不過超時單位是秒:jdbc:postgresql://localhost/test?user=fred&password=secret&&cnotallow=60&socketTimeout=60
- oracle 的 thin jdbc driver 不支持通過 URL 參數指定套接字的連接超時和讀寫超時,而是需要通過系統參數 oracle.net.CONNECT_TIMEOUT 和 oracle.jdbc.ReadTimeout 來分別指定,這兩個參數的單位都是毫秒,默認值都是0,(讀寫超時參數,在 10.1.0.5 以下版本的驅動中是 oracle.net.READ_TIMEOUT,在 10.1.0.5 以上的版本中才是 oracle.jdbc.ReadTimeout),比如可以通過 OracleDatasource.setConnectionProperties(java.util.Properties prop) 指定,使用 DBCP 時可以通過 BasicDatasource.setConnectionProperties(java.util.Properties prop)或 BasicDatasource.addConnectionProperties(java.util.Properties prop)指定;
圖片
圖片
# 配置參數
finalstatic String url= "jdbc:oracle:thin:@myhost:1521/myorcldbservicename";
finalstatic String user = "hr";
finalstatic String password = "hr";
finalstatic String CONNECT_TIMEOUT = "20000";
finalstatic String READ_TIMEOUT = "50000";
# 使用 DataSource 獲取連接
Properties connectionProperties = new Properties();
connectionProperties.put(“oracle.net.CONNECT_TIMEOUT”, CONNECT_TIMEOUT);
connectionProperties.put(“oracle.jdbc.ReadTimeout”, READ_TIMEOUT);
OracleDataSource ods = new OracleDataSource();
ods.setURL(url);
ods.setUser(user);
ods.setPassword(password);
ods.setConnectionProperties(connectionProperties);
# 使用 DriverManager 獲取連接
Class<?> oracleDriverClass = Class.forName("oracle.jdbc.driver.OracleDriver");
Properties connectionProperties = new Properties();
connectionProperties.put(“oracle.net.CONNECT_TIMEOUT”, CONNECT_TIMEOUT);
connectionProperties.put(“oracle.jdbc.ReadTimeout”, READ_TIMEOUT);
//也可以通過環境變量/系統參數設置,注意需要在 connection 連接之前設置
//System.setProperty("oracle.net.CONNECT_TIMEOUT", connectTimeout);
//System.setProperty("oracle.jdbc.ReadTimeout", readTimeout);
connectionProperties.put(“user”, user);
connectionProperties.put(“password”, password);
Connection cnotallow=DriverManager.getConnection(url, props);
12 操作系統或TCP套接字級別的 TCP 超時檢測機制
除了以上幾個常見的數據庫超時參數,還需要注意,客戶端的JDBC應用程序和服務端的數據庫管理系統,在服務器上都有操作系統級別的基于 tcp keep-alive 的超時檢測和保活機制;如果操作系統支持,客戶端的JDBC應用程序和服務端的數據庫管理系統,甚至也可能配置 TCP 套接字級別的基于 tcp keep-alive的超時檢測和保活機制。
- 當應用系統沒有指定數據庫的連接超時和套接字超時時,應用系統大部分情況下都不能有效檢測到網絡故障。因此,當網絡錯誤發生后,在應用系統成功重新建立連接前或成功讀取到數據前,應用系統都會無限制地一直處于等待狀態;
- 為避免上述狀況,管理員一般會在服務器上配置基于 tcp keep-alive 的超時檢測和保活機制,從而在服務器的操作系統層面主動對網絡連接進行校驗;
- 比如在 linux 服務器上將 tcp-keepalive 的檢測間隔配置為30分鐘后,在遇到網絡問題時,即使應用系統沒有在 JDBC 數據庫驅動中指定套接字超時(或指定為0),因為網絡問題造成的數據庫連接問題的持續時間也不會超過30分鐘;
- linux下,操作系統級別的套接字超時檢測機制,主要跟以下幾個內核參數相關,可以通過 sysctl 命令查看和更改這些內核參數;
/proc/sys/net/ipv4/tcp_keepalive_intvl: 默認 75秒,The number of seconds between TCP keep-alive probes;
/proc/sys/net/ipv4/tcp_keepalive_probes: 默認 9 次,The maximum number of TCP keep-alive probes to send before giving up and killing the connection if no response is obtained from the other end;
/proc/sys/net/ipv4/tcp_keepalive_time: 默認 7200 秒即2小時,The number of seconds a connection needs to be idle before TCP begins sending out keep-alive probes. Keep-alives are sent only when the SO_KEEPALIVE socket option is enabled. An idle connection is terminated after approximately an additional 11 minutes (9 probes an interval of 75 seconds apart) when keep-alive is enabled;
- LINUX 操作系統也支持配置套接字級別的基于 tcp keep-alive的超時檢測和保活機制,相關 socket 套接字選項如下:
- TCP_KEEPIDLE:the amount of time until the first keepalive packet is sent;
- TCP_KEEPCNT:the number of probes to send;
- TCP_KEEPINTVL:the interval between keepalive packets;
- 具體配置方式跟編程語言提供的 socket api 有關,JDK8/JDK11 通過 jdk.net.ExtendedSocketOptions 提供了對套接字級別的基于 tcp keep-alive的超時檢測和保活機制的支持,所以可以如下配置:
import java.net.Socket;
import jdk.net.ExtendedSocketOptions;
Socket socket = new Socket();
socket.setOption(ExtendedSocketOptions.TCP_KEEPIDLE, 10);
socket.setOption(ExtendedSocketOptions.TCP_KEEPCOUNT, 2);
socket.setOption(ExtendedSocketOptions.TCP_KEEPINTERVAL, 3);
- ORACLE 數據庫管理系統在 LINUX 操作系統上,在 12c 及以上版本,如果用戶配置了sqlnet.ora: SQLNET.EXPIRE_TIME=5,在底層就是通過配置套接字參數 TCP_KEEPIDLE/TCP_KEEPCNT/TCP_KEEPINTVL,在套接字級別實現了基于 tcp keep-alive的超時檢測和保活機制;(相關配置參數有:sqlnet.ora: SQLNET.EXPIRE_TIME=5/SQLNET.INBOUND_CONNECT_TIMEOUT=600;listener.ora: INBOUND_CONNECT_TIMEOUT_<listener_name>=240)
# 查詢內核參數
- sysctl -a //顯示當前所有可用的內核參數
- sysctl net.ipv4.tcp_keepalive_time //查詢某個內核參數
- cat /proc/sys/net/ipv4/tcp_keepalive_time //查詢某個內核參數
#修改內核參數
- sysctl net.ipv4.tcp_keepalive_time=3600//修改某個內核參數
- vim /etc/sysctl.conf//在配置文件中修改內核參數
- sysctl -p //從配置文件 sysctl.conf 中重新加載內核參數
- If the socket timeout or the connect timeout is not configured, most of the time, applications cannot detect network errors. So, until the applications are connected or are able to read data, they will wait indefinitely.
- To prevent this, we can configure a socket timeout time at the OS level, so the Linux servers can check the network connection at the OS level.
- If you set the KeepAlive checking cycle for the Linux servers to 30 minutes, then even if someone set the JDBC driver‘s socket timeout to 0, which means no timeout, the DBMS network connection problems caused by network issues do not surpass 30 minutes/The JDBC connection hang recovers 30 minutes after the network connection failure, that is to say, the JDBC driver's socket timeout is affected by the OS's socket timeout configuration.
- Generally, the application hangs from network issues when the application is calling Socket.read(). However, depending on the network composition or the error type, it can rarely be in waiting status while running Socket.write(). When the application calls Socket.write(), the data is recorded to the OS kernel buffer and then the right to control is returned to the application immediately. Thus, as long as a valid value is recorded to the kernel buffer, Socket.write() is always successful. However, if the OS kernel buffer is full due to a special network error, even Socket.write() can be put into waiting status. In thiscase, the OS tries to resend the packet for a certain amount of time, and generates an error when it reaches the limit.
13 相關源碼與參考連接
# JDBC API 相關類與方法
java.sql.DriverManager#setLoginTimeout
javax.sql.CommonDataSource#setLoginTimeout
java.sql.Connection#getNetworkTimeout
java.sql.Connection#setNetworkTimeout
java.sql.Statement#setQueryTimeout
# oracle JDBC driver 相關類與方法
oracle.jdbc.OracleDriver
oracle.jdbc.pool.OracleDataSource#setLoginTimeout
oracle.jdbc.OracleConnection
oracle.jdbc.OracleConnection#CONNECTION_PROPERTY_THIN_READ_TIMEOUT
oracle.jdbc.OracleConnection#CONNECTION_PROPERTY_THIN_NET_CONNECT_TIMEOUT。
oracle.jdbc.OracleConnectionWrapper#setNetworkTimeout
oracle.jdbc.driver.PhysicalConnection#setNetworkTimeout
oracle.jdbc.driver.OracleStatement#setQueryTimeout
oracle.jdbc.driver.OracleStatement#doExecuteWithTimeout
oracle.jdbc.driver.OraclePreparedStatement#executeForRowsWithTimeout
oracle.jdbc.driver.OracleTimeoutPollingThread
# mysql JDBC driver 相關類與方法
com.mysql.cj.jdbc.Driver
com.mysql.cj.jdbc.MysqlDataSource#setLoginTimeout
com.mysql.cj.jdbc.ConnectionImpl#setNetworkTimeout
com.mysql.cj.jdbc.ConnectionWrapper#setNetworkTimeout
com.mysql.cj.jdbc.StatementImpl#setQueryTimeout
com.mysql.cj.jdbc.StatementWrapper#setQueryTimeout
#參考鏈接
- https://www.cubrid.org/blog/3826470
- https://prashantatridba.wordpress.com/tag/tcp_keepidle/
- https://bugs.openjdk.org/browse/JDK-8194298