深入理解 JDBC 的超時(shí)

這是最近讀到的講關(guān)于 JDBC 的超時(shí)問(wèn)題最透徹的文章,原文是http://www.cubrid.org/blog/understanding-jdbc-internals-and-timeout-configuration 懦鼠,網(wǎng)上現(xiàn)有的翻譯感覺(jué)磕磕絆絆的粱快,很多上下文信息丟失了,這里用我的理解重新翻譯一下沿腰。

應(yīng)用程序中配置恰當(dāng)?shù)?JDBC 超時(shí)時(shí)間能減少服務(wù)失敗的時(shí)間览徒,這篇文章我們將討論不同種類(lèi)的超時(shí)和推薦的配置。

Web 應(yīng)用服務(wù)器在 DDoS 攻擊后變得無(wú)響應(yīng)

(這是一個(gè)真實(shí)案例的發(fā)生過(guò)程復(fù)述)

在 DDoS 攻擊之后颂龙,整個(gè)服務(wù)都不能正常工作了习蓬,因?yàn)榈谒膶咏粨Q機(jī)不能工作,網(wǎng)絡(luò)連接斷開(kāi)了措嵌,這也導(dǎo)致 WAS (可以將 WAS 理解為作者公司的應(yīng)用程序)不能正常工作躲叼。攻擊發(fā)生后不久,安全團(tuán)隊(duì)攔截了所有 DDoS 攻擊企巢,然后網(wǎng)絡(luò)恢復(fù)正常枫慷,但 WAS 還是不能工作。

通過(guò)分析系統(tǒng)的 dump 日志發(fā)現(xiàn)浪规,業(yè)務(wù)系統(tǒng)停在了 JDBC API 的調(diào)用上或听。20分鐘后系統(tǒng)仍處于等待狀態(tài)無(wú)法響應(yīng),大概過(guò)了30分鐘笋婿,系統(tǒng)突然發(fā)生異常誉裆,然后服務(wù)恢復(fù)正常。

為什么已經(jīng)將查詢(xún)超時(shí)時(shí)間設(shè)置成3秒缸濒, WAS 卻等待了30分鐘足丢?為什么30分鐘后 WAS 又開(kāi)始工作了?

如果理解了 JDBC 的超時(shí)機(jī)制就能找到答案庇配。

為什么我們需要知道 JDBC 驅(qū)動(dòng)

當(dāng)有性能問(wèn)題或系統(tǒng)級(jí)錯(cuò)誤時(shí)斩跌,WAS 和數(shù)據(jù)庫(kù)是我們關(guān)注的兩個(gè)重要層面。在我公司 WAS 和數(shù)據(jù)庫(kù)通常由不同的部門(mén)負(fù)責(zé)讨永,因此每個(gè)部門(mén)聚焦在各自負(fù)責(zé)的領(lǐng)域來(lái)設(shè)法弄清楚狀況滔驶。此時(shí) WAS 和數(shù)據(jù)庫(kù)之間的部分會(huì)因?yàn)榈貌坏阶銐虻年P(guān)注而產(chǎn)生盲區(qū)。對(duì)于 Java 應(yīng)用卿闹,這個(gè)盲區(qū)在數(shù)據(jù)庫(kù)連接池和 JDBC 之間揭糕,本文我們將重點(diǎn)討論 JDBC萝快。

什么是 JDBC 驅(qū)動(dòng)

JDBC 是 Java 應(yīng)用程序中用于訪問(wèn)數(shù)據(jù)庫(kù)的一套標(biāo)準(zhǔn) API,Sun 公司定義了4種類(lèi)型的 JDBC 驅(qū)動(dòng)著角。我公司主要用的是第4種揪漩,該類(lèi)型驅(qū)動(dòng)由純 Java 語(yǔ)言編寫(xiě),在 Java 應(yīng)用中通過(guò) socket 與數(shù)據(jù)庫(kù)通信吏口。

圖1: 類(lèi)型4驅(qū)動(dòng)

類(lèi)型4驅(qū)動(dòng)是通過(guò) socket 來(lái)處理字節(jié)流的奄容,它的基本操作和 HttpClient 這種網(wǎng)絡(luò)操作類(lèi)庫(kù)相同。同其他網(wǎng)絡(luò)類(lèi)庫(kù)一樣产徊,也會(huì)在發(fā)生超時(shí)的時(shí)候占用大量的 CPU 資源從而失去響應(yīng)昂勒。如果你之前用過(guò) HttpClient ,肯定遇到過(guò)因?yàn)闆](méi)有設(shè)置超時(shí)導(dǎo)致的錯(cuò)誤舟铜。如果 socket 超時(shí)設(shè)置不合適戈盈,類(lèi)型4驅(qū)動(dòng)也可能有同樣的錯(cuò)誤(連接被阻塞)。

下面讓我們了解如何配置 JDBC 驅(qū)動(dòng)的 socket 超時(shí)谆刨,以及設(shè)置時(shí)需考慮哪些問(wèn)題塘娶。

WAS 與數(shù)據(jù)庫(kù)間的設(shè)置超時(shí)的層次

圖2: 超時(shí)的層次

圖2展示了簡(jiǎn)化的 WAS 和數(shù)據(jù)庫(kù)通信時(shí)的超時(shí)層次。

更上層的超時(shí)依賴(lài)于下層的超時(shí)痊夭,只有當(dāng)較低層的超時(shí)機(jī)制正常工作刁岸,上層的超時(shí)才會(huì)正常。如果 JDBC 驅(qū)動(dòng)程序的 socket 超時(shí)工作不正常她我,那么更上層的超時(shí)比如 Statement 超時(shí)和事務(wù)超時(shí)都不會(huì)正常工作虹曙。

我們收到很多評(píng)論說(shuō):

即使配置了 Statement 超時(shí),應(yīng)用程序還是不能從故障中恢復(fù)鸦难,因?yàn)?Statement 超時(shí)在網(wǎng)絡(luò)故障時(shí)不起作用根吁。

Statement 超時(shí)在網(wǎng)絡(luò)故障時(shí)不起作用。它只能做到:限制一次Statement 執(zhí)行的時(shí)間合蔽,處理超時(shí)以防網(wǎng)絡(luò)故障必須由 JDBC 驅(qū)動(dòng)來(lái)做。

JDBC 驅(qū)動(dòng)的 socket 超時(shí)還會(huì)受操作系統(tǒng)的 socket 超時(shí)配置的影響介返。這解釋了為什么案例中的 JDBC 連接在網(wǎng)絡(luò)故障后阻塞了30分鐘才恢復(fù)拴事,即使沒(méi)配置 JDBC 驅(qū)動(dòng)的 socket 超時(shí)。

DBCP 連接池位于圖2的左邊圣蝎。你會(huì)發(fā)現(xiàn)各種層面的超時(shí)與 DBCP 是分開(kāi)的刃宵。DBCP 負(fù)責(zé)數(shù)據(jù)庫(kù)連接(即本文中說(shuō)到的Connection)的創(chuàng)建和管理,并不涉及超時(shí)的處理徘公。當(dāng)在 DBCP 中創(chuàng)建了一個(gè)數(shù)據(jù)庫(kù)連接或發(fā)送了一條查詢(xún)校驗(yàn)的 sql 語(yǔ)句用于檢查連接有效性時(shí)牲证,socket 超時(shí)會(huì)影響這些過(guò)程的處理,但并不直接影響應(yīng)用程序关面。

然而在應(yīng)用程序中調(diào)用 DBCP 的 getConnection() 方法時(shí)坦袍,你能指定應(yīng)用程序獲取數(shù)據(jù)庫(kù)連接的超時(shí)時(shí)間十厢,但這和 JDBC 的連接超時(shí)無(wú)關(guān)。

圖3: 每一層級(jí)的超時(shí)

什么是事務(wù)超時(shí)

事務(wù)超時(shí)是在框架(Spring捂齐、EJB容器)或應(yīng)用程序?qū)用嫔喜庞行У某瑫r(shí)蛮放。

事務(wù)超時(shí)可能是個(gè)不常見(jiàn)的概念。簡(jiǎn)單講奠宜,事務(wù)超時(shí)等于** Statement 超時(shí) * N(需要執(zhí)行的 Statement 的數(shù)量) + 其它(垃圾回收等其他時(shí)間)**包颁。事務(wù)超時(shí)被用來(lái)限制執(zhí)行一個(gè)事務(wù)之內(nèi)所有 Statement 執(zhí)行的總時(shí)長(zhǎng)。

比如压真,假設(shè)執(zhí)行一次 Statement 執(zhí)行需0.1秒娩嚼,那執(zhí)行幾次 Statement
并不是什么問(wèn)題,但如果是執(zhí)行十萬(wàn)次則需要一萬(wàn)秒(大約7個(gè)小時(shí))滴肿,這就可以用上事務(wù)超時(shí)了待锈。

EJB 的聲明式事務(wù)管理 (容器管理事務(wù)) 就是一種典型的使用場(chǎng)景,但聲明式事務(wù)管理只是定義了相應(yīng)的規(guī)范嘴高,容器內(nèi)事務(wù)的處理過(guò)程和具體實(shí)現(xiàn)由容器的開(kāi)發(fā)者負(fù)責(zé)竿音。我們公司并沒(méi)有用 EJB,用的是最常見(jiàn)的 Spring 框架拴驮,所以事務(wù)超時(shí)的配置也由 Spring 來(lái)管理春瞬。在 Spring 中,事務(wù)超時(shí)可以在 XML 文件顯式配置或在 Java 代碼中用 Transactional 注解來(lái)配置套啤。

<tx:attributes>
        <tx:method name="…" timeout="3"/>
</tx:attributes>

Spring 提供的事務(wù)超時(shí)的配置非常簡(jiǎn)單宽气,它會(huì)記錄每個(gè)事務(wù)的開(kāi)始時(shí)間和消耗時(shí)間,當(dāng)特定的事件發(fā)生時(shí)會(huì)對(duì)已消耗掉的時(shí)間做校驗(yàn)潜沦,如果超出了配置將拋出異常萄涯。

Spring 中數(shù)據(jù)庫(kù)連接被保存在線程本地變量(ThreadLocal)中,這被稱(chēng)作事務(wù)同步(Transaction Synchronization)唆鸡。當(dāng)數(shù)據(jù)庫(kù)連接被保存到 ThreadLocal 時(shí)涝影,同時(shí)會(huì)記錄事務(wù)的開(kāi)始時(shí)間和超時(shí)時(shí)間。所以通過(guò)數(shù)據(jù)庫(kù)連接的代理創(chuàng)建的 Statement 在執(zhí)行時(shí)就會(huì)校驗(yàn)這個(gè)時(shí)間争占。

EJB 的聲明式事務(wù)管理的實(shí)現(xiàn)也是類(lèi)似燃逻,實(shí)現(xiàn)的思路非常簡(jiǎn)單。如果事務(wù)超時(shí)非常重要臂痕,但你所使用的容器或框架不提供此功能伯襟,你也可以選擇自己實(shí)現(xiàn),關(guān)于事務(wù)超時(shí)并沒(méi)有制定標(biāo)準(zhǔn)的 API握童。

Lucy 框架的1.5和1.6版不支持事務(wù)超時(shí)姆怪,但你可以通過(guò) Spring 的事務(wù)管理達(dá)到相同的效果。

假設(shè)一個(gè)事務(wù)里有5條 Statement ,每條 Statement 執(zhí)行時(shí)間是200毫秒稽揭,其它業(yè)務(wù)邏輯或框架操作的執(zhí)行時(shí)間是100毫秒俺附,那事務(wù)允許的超時(shí)時(shí)間至少應(yīng)該1100毫秒(200 * 5 + 100)。

什么是 Statement 超時(shí)

Statement 超時(shí)是用來(lái)限制 Statement 的執(zhí)行時(shí)間的淀衣,它的具體值是通過(guò) JDBC API 來(lái)設(shè)置的昙读。JDBC 驅(qū)動(dòng)程序基于這個(gè)值進(jìn)行 Statement 執(zhí)行時(shí)的超時(shí)處理。Statement 超時(shí)是通過(guò) JDBC API 中java.sql.Statement 類(lèi)的 setQueryTimeout(int timeout) 方法配置的膨桥。不過(guò)現(xiàn)在的開(kāi)發(fā)者已經(jīng)很少直接在代碼中配置它了蛮浑,更多是通過(guò)框架來(lái)進(jìn)行設(shè)置。

以 iBatis 為例只嚣,可以通過(guò) SqlMapConfig.xml 中的 setting 屬性defaultStatementTimeout 來(lái)設(shè)置全局的 statement 超時(shí)缺省值沮稚。你也可以通過(guò)在具體的 sql 映射文件中的 select insert update 標(biāo)簽的 statement 屬性來(lái)覆蓋。

當(dāng)你用 Lucy 1.5或1.6版時(shí)册舞,可以通過(guò)設(shè)置 queryTimeout 屬性在數(shù)據(jù)源層面設(shè)置 Statement 超時(shí)蕴掏。

Statement 超時(shí)的具體數(shù)值需要根據(jù)每個(gè)應(yīng)用自身的情況而定,并沒(méi)有推薦的配置调鲸。

JDBC 驅(qū)動(dòng)中的 Statement 超時(shí)處理過(guò)程

每個(gè)數(shù)據(jù)庫(kù)和驅(qū)動(dòng)程序的 Statement 超時(shí)的處理也是不同的盛杰。Oracle 和 SQLServer 的工作方式比較像,MySQL 和 CUBRID 比較像藐石。

Oracle 中的 Statement 超時(shí)處理

  1. 調(diào)用 Connection 的 createStatement() 方法創(chuàng)建一個(gè) Statement 對(duì)象
  2. 調(diào)用 Statement 的 executeQuery() 方法
  3. Statement 通過(guò)內(nèi)部綁定的 Connection 對(duì)象將查詢(xún)命令發(fā)送到 Oracle 數(shù)據(jù)庫(kù)
  4. Statement 向 Oracle 的超時(shí)處理線程 OracleTimeoutPollingThread(每個(gè)類(lèi)加載器一個(gè)該線程)注冊(cè)一個(gè) Statement 用于處理超時(shí)
  5. 發(fā)生超時(shí)
  6. Oracle 的 OracleTimeoutPollingThread 調(diào)用 OracleStatement 的 cancel() 方法
  7. 通過(guò) Statement 的 Connection 發(fā)送一條消息取消還在執(zhí)行的查詢(xún)
圖4 Oracle 的 Statement 超時(shí)執(zhí)行過(guò)程

JTDS (MS SQLServer) 中的 Statement 超時(shí)處理

1.調(diào)用 Connection 的 createStatement() 方法創(chuàng)建一個(gè) Statement 對(duì)象

  1. 調(diào)用 Statement 的 executeQuery() 方法
  2. Statement 通過(guò)內(nèi)部的 Connection 將查詢(xún)命令發(fā)送到 MS SqlServer 數(shù)據(jù)庫(kù)
  3. Statement 向 MS SQLServer 的 TimerThread 線程注冊(cè)一個(gè) Statement 用于處理超時(shí)
  4. 發(fā)生超時(shí)
  5. TimerThread 調(diào)用 JtdsStatement 內(nèi)部的 TsdCore.cancel()方法
  6. 通過(guò) ConnectionJDBC 發(fā)送一條消息取消還在執(zhí)行的查詢(xún)
圖5 MS SQLServer 的 Statement 超時(shí)執(zhí)行過(guò)程

MySQL (5.0.8) 中的 Statement 超時(shí)處理

  1. 調(diào)用 Connection 的 createStatement() 方法創(chuàng)建一個(gè) Statement 對(duì)象
  2. 調(diào)用 Statement 的 executeQuery() 方法
  3. Statement 通過(guò)內(nèi)部的 Connection 將查詢(xún)命令傳輸?shù)? MySqlServer 數(shù)據(jù)庫(kù)
  4. Statement 創(chuàng)建一個(gè)新的超時(shí)執(zhí)行線程(timeout-execution)來(lái)處理超時(shí)
  5. 5.1以上版本改為每個(gè)連接分配一個(gè)線程
  6. 向 timeout-execution 線程注冊(cè)當(dāng)前的 Statement
  7. 發(fā)生超時(shí)
  8. timeout-execution 線程創(chuàng)建一個(gè)相同配置的 Connection
  9. 用新創(chuàng)建的 Connection 發(fā)送取消查詢(xún)的命令
圖6 MySQL 的 Statement 超時(shí)執(zhí)行過(guò)程

CUBRID中的 Statement 超時(shí)處理

  1. 調(diào)用 Connection 的 createStatement() 方法創(chuàng)建一個(gè) Statement 對(duì)象
  2. 調(diào)用 Statement 的 executeQuery() 方法
  3. Statement 通過(guò)內(nèi)部的 Connection 將查詢(xún)命令發(fā)送到 CUBRID 數(shù)據(jù)庫(kù)
  4. Statement 創(chuàng)建一個(gè)新的超時(shí)執(zhí)行線程(timeout-execution)來(lái)處理超時(shí)
  5. 向 timeout-execution 線程注冊(cè)當(dāng)前的 Statement
  6. 發(fā)生超時(shí)
  7. timeout-execution 線程創(chuàng)建一個(gè)相同配置的Connection
  8. 用新創(chuàng)建的 Connection 發(fā)送取消查詢(xún)的命令
圖7 CUBRID 的 Statement 超時(shí)執(zhí)行過(guò)程

什么是 Socket 超時(shí)

類(lèi)型4的 JDBC 驅(qū)動(dòng)是用 Socket 方式與數(shù)據(jù)庫(kù)連接的即供,應(yīng)用程序和數(shù)據(jù)庫(kù)之間的連接超時(shí)并不是由數(shù)據(jù)庫(kù)處理的。

當(dāng)數(shù)據(jù)庫(kù)突然宕掉或發(fā)生網(wǎng)絡(luò)錯(cuò)誤(設(shè)備故障等)時(shí)于微,JDBC 驅(qū)動(dòng)的 Socket 超時(shí)的值是必須的昼榛。由于 TCP/IP 的結(jié)構(gòu)脆烟,Socket 沒(méi)有辦法檢測(cè)到網(wǎng)絡(luò)錯(cuò)誤,因此應(yīng)用不能檢測(cè)到與數(shù)據(jù)庫(kù)到連接斷開(kāi)了啊掏。如果沒(méi)有設(shè)置 Socket 超時(shí)冷离,應(yīng)用程序會(huì)一直等待數(shù)據(jù)庫(kù)返回結(jié)果度帮。(這個(gè)連接也被叫做“死連接”) 為了避免死連接唧领,Socket 必須要設(shè)置超時(shí)時(shí)間焰手。Socket 超時(shí)可以通過(guò) JDBC 驅(qū)動(dòng)程序配置。通過(guò)設(shè)置 Socket 超時(shí)吗坚,可以防止出現(xiàn)網(wǎng)絡(luò)錯(cuò)誤時(shí)一直等待的情況并縮短故障時(shí)間祈远。

不推薦使用 Socket 超時(shí)來(lái)限制一個(gè) Statement 的執(zhí)行時(shí)間,因此Socket 超時(shí)的值必須要高于 Statement 的超時(shí)時(shí)間商源,否則 Socket 超時(shí)將會(huì)先生效,這樣 Statement 超時(shí)就沒(méi)有意義谋减,也無(wú)法生效牡彻。

下面展示了 Socket 超時(shí)設(shè)置的連個(gè)選項(xiàng),其配置因不同的驅(qū)動(dòng)而異。

  • Socket 連接時(shí)的超時(shí):通過(guò) Socket 對(duì)象的 connect(SocketAddress endpoint, int timeout) 方法來(lái)配置
  • Socket 讀寫(xiě)時(shí)的超時(shí):通過(guò) Socket 對(duì)象的 setSoTimeout(int timeout) 方法來(lái)配置

通過(guò)查看CUBRID庄吼,MySQL缎除,MS SQL Server (JTDS) 和 Oracle 的JDBC 驅(qū)動(dòng)源碼,我們確認(rèn)以上所有驅(qū)動(dòng)都是使用上面的2個(gè) API 來(lái)設(shè)置socket 超時(shí)的总寻。

下面列出了如何配置 Socket 超時(shí)

JDBC 驅(qū)動(dòng) 連接超時(shí)配置 Socket 超時(shí)配置 JDBC Url 格式 示例
MySQL connectTimeout(默認(rèn)值:0器罐,單位:毫秒) socketTimeout(默認(rèn)值:0,單位:ms) jdbc:mysql://[host:port],[host:port].../[database]
[?propertyName1][=propertyValue1][&propertyName2][=propertyValue2]...
jdbc:mysql://xxx.xx.xxx.xxx:3306/database?connectTimeout=60000&socketTimeout=60000
MS-SQL , jTDS loginTimeout(默認(rèn)值:0渐行,單位:秒) socketTimeout(默認(rèn)值:0轰坊,單位:s) jdbc:jtds:<server_type>://<server>[:<port>][/<database>][;<property>=<value>[;...]] jdbc:jtds:sqlserver://server:port/database;loginTimeout=60;socketTimeout=60
Oracle oracle.net.CONNECT_TIMEOUT (默認(rèn)值:0,單位:毫秒) oracle.jdbc.ReadTimeout(默認(rèn)值:0祟印,單位:毫秒) 不支持通過(guò)url配置肴沫,只能通過(guò)OracleDatasource.setConnectionProperties() API設(shè)置,使用DBCP時(shí)可以調(diào)用BasicDatasource.setConnectionProperties()或BasicDatasource.addConnectionProperties()進(jìn)行設(shè)置 -
CUBRID 無(wú)單獨(dú)配置項(xiàng)(默認(rèn)值:5,000蕴忆,單位:毫秒) 無(wú)單獨(dú)配置項(xiàng)(默認(rèn)值:5,000颤芬,單位:毫秒) - -
  • connectTimeout 和 socketTimeout 的默認(rèn)值是 0 ,這意味著不會(huì)發(fā)生超時(shí)套鹅。
  • 你也可以通過(guò)屬性進(jìn)行配置站蝠,而無(wú)需直接使用 DBCP 的 API 。

通過(guò)屬性進(jìn)行配置時(shí)卓鹿,需要傳入的 key 為 "connectionProperties"菱魔,其 value 的格式為" [propertyName=property;]*"。下面是 iBatis 中通過(guò) xml 文件配置屬性的例子减牺。

<transactionManager type="JDBC">
  <dataSource type="com.nhncorp.lucy.db.DbcpDSFactory">
     ....
     <property name="connectionProperties" value="oracle.net.CONNECT_TIMEOUT=6000;oracle.jdbc.ReadTimeout=6000"/> 
  </dataSource>
</transactionManager>

操作系統(tǒng)層面的 Socket 超時(shí)配置

如果沒(méi)設(shè)置 Socket 超時(shí)或連接超時(shí)豌习,應(yīng)用程序多數(shù)情況下無(wú)法檢測(cè)到網(wǎng)絡(luò)錯(cuò)誤。此時(shí)拔疚,應(yīng)用程序?qū)⒁恢钡却氯シ事。钡竭B接上數(shù)據(jù)庫(kù)或能讀取到數(shù)據(jù)。然而稚失,如果查看實(shí)際服務(wù)遇到的實(shí)際情況會(huì)發(fā)現(xiàn)問(wèn)題常常在在應(yīng)用程序(WAS)在30分鐘后嘗試重新連接到網(wǎng)絡(luò)后被解決了栋艳。這是因?yàn)椴僮飨到y(tǒng)也配置了 Socket 超時(shí)時(shí)間。我公司使用的 Linux 服務(wù)器將 Socket 超時(shí)時(shí)間設(shè)置為30分鐘句各。它將在操作系統(tǒng)層面對(duì)網(wǎng)絡(luò)連接做校驗(yàn)吸占。因?yàn)楣镜?Linux 服務(wù)器的 KeepAlive 檢查周期為30分鐘,因此即使應(yīng)用程序里將 Socket 超時(shí)設(shè)置為0凿宾,由網(wǎng)絡(luò)原因引起的數(shù)據(jù)庫(kù)網(wǎng)絡(luò)連接問(wèn)題也不會(huì)超過(guò)30分鐘矾屯。

通常,應(yīng)用程序會(huì)在調(diào)用 Socket 的 read() 方法時(shí)由于網(wǎng)絡(luò)問(wèn)題而阻塞住初厚。然而很少在調(diào)用 Socket 的 write() 方法時(shí)處于等待狀態(tài)件蚕,這取決于網(wǎng)絡(luò)構(gòu)成和錯(cuò)誤類(lèi)型。當(dāng)應(yīng)用程序調(diào)用 Socket 的 write() 方法時(shí),數(shù)據(jù)被記錄到操作系統(tǒng)的內(nèi)核緩沖區(qū)排作,然后將控制權(quán)立即交還給應(yīng)用程序牵啦。因此,一旦數(shù)據(jù)已經(jīng)寫(xiě)入內(nèi)核緩沖區(qū)妄痪,write() 的調(diào)用始終是成功哈雏。但是,如果操作系統(tǒng)內(nèi)核緩沖區(qū)由于特殊的網(wǎng)絡(luò)錯(cuò)誤而滿了的話衫生,write() 方法也會(huì)進(jìn)入等待狀態(tài)裳瘪。這種情況下,操作系統(tǒng)會(huì)嘗試重新發(fā)送數(shù)據(jù)包一段時(shí)間障簿,并在達(dá)到超時(shí)限制時(shí)產(chǎn)生錯(cuò)誤盹愚。 在公司的 Linux服務(wù)器上這種情況的超時(shí)時(shí)間設(shè)置為15分鐘。

至此站故,我已經(jīng)解釋了 JDBC 的內(nèi)部操作皆怕,希望這將幫助你正確的超時(shí)配置超時(shí)時(shí)間從而減少錯(cuò)誤。

至此西篓,我已經(jīng)對(duì)JDBC的內(nèi)部操作做了講解愈腾,希望能夠讓大家學(xué)會(huì)如何正確的配置超時(shí)時(shí)間,從而減少錯(cuò)誤的發(fā)生岂津。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末虱黄,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子吮成,更是在濱河造成了極大的恐慌橱乱,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件粱甫,死亡現(xiàn)場(chǎng)離奇詭異泳叠,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)茶宵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)危纫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人乌庶,你說(shuō)我怎么就攤上這事种蝶。” “怎么了瞒大?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵螃征,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我透敌,道長(zhǎng)会傲,這世上最難降的妖魔是什么锅棕? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任拙泽,我火速辦了婚禮淌山,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘顾瞻。我一直安慰自己泼疑,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布荷荤。 她就那樣靜靜地躺著退渗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蕴纳。 梳的紋絲不亂的頭發(fā)上会油,一...
    開(kāi)封第一講書(shū)人閱讀 49,821評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音古毛,去河邊找鬼翻翩。 笑死,一個(gè)胖子當(dāng)著我的面吹牛稻薇,可吹牛的內(nèi)容都是我干的嫂冻。 我是一名探鬼主播,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼塞椎,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼桨仿!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起案狠,我...
    開(kāi)封第一講書(shū)人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤服傍,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后骂铁,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體吹零,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年从铲,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了瘪校。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡名段,死狀恐怖阱扬,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情伸辟,我是刑警寧澤麻惶,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站信夫,受9級(jí)特大地震影響窃蹋,放射性物質(zhì)發(fā)生泄漏卡啰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一警没、第九天 我趴在偏房一處隱蔽的房頂上張望匈辱。 院中可真熱鬧,春花似錦杀迹、人聲如沸亡脸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)浅碾。三九已至,卻和暖如春续语,著一層夾襖步出監(jiān)牢的瞬間垂谢,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工疮茄, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留滥朱,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓娃豹,卻偏偏與公主長(zhǎng)得像焚虱,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子懂版,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容