最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Mysql中的超時時間設(shè)置方式

 更新時間:2024年01月29日 08:45:47   作者:magic_kid_2010  
這篇文章主要介紹了Mysql中的超時時間設(shè)置方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

1、建立數(shù)據(jù)庫連接超時設(shè)置

jdbc:mysql://localhost:3306/gjm?connectTimeout=3000

  • connectTimeout:表示的是數(shù)據(jù)庫驅(qū)動(mysql-connector-java) 與 mysql服務(wù)器建立TCP連接的超時時間。屬于TCP層面的超時。

假設(shè)正常與數(shù)據(jù)建立連接需要3ms,我們可以通過設(shè)置 connectTimeout=1ms 來模擬。

將會出現(xiàn)如下錯誤:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failureThe last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.    
  at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)    
  at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)    
  ...
Caused by: java.net.SocketTimeoutException: connect timed out    
  at java.net.PlainSocketImpl.socketConnect(Native Method)    
  at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)    
  ...

當(dāng)拋出異常后,調(diào)用 conn.isClosed() 返回 true。 

2、socket 讀取超時設(shè)置

jdbc:mysql://localhost:3306/gjm?connectTimeout=1000&socketTimeout=60000

  • socketTimeout:是通過TCP連接發(fā)送數(shù)據(jù)(要執(zhí)行的sql)后,等待響應(yīng)的超時時間。屬于TCP層面的超時。

我們可以通過在查詢中設(shè)置 sleep(n) 來進行模擬。

將會出現(xiàn)如下錯誤:

Last packet sent to the server was 60000 ms ago.
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
    at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1074)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2985)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2871)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3414)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1936)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2060)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2536)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2465)
    at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1383)
    ...
Caused by: java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:171)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:113)
    at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:160)
    at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:188)
    at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2428)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2882)
    ... 9 more

當(dāng)拋出異常后,調(diào)用 conn.isClosed() 返回 true。 

3、單個 sql 執(zhí)行超時設(shè)置

Connection conn = datasource.getConnection();
PreparedStatement ps = conn.prepareStatement("select sleep(5)"); // 設(shè)置服務(wù)端休眠5秒再返回
ps.setQueryTimeout(1); // 設(shè)置語句執(zhí)行超時時間為1秒

將出現(xiàn)如下錯誤:

com.mysql.jdbc.exceptions.MySQLTimeoutException: Statement cancelled due to timeout or client request
  at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1881)    
  at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1962)    
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)    
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)    
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)    
  at java.lang.reflect.Method.invoke(Method.java:498)    
  at org.apache.tomcat.jdbc.pool.StatementFacade$StatementProxy.invoke(StatementFacade.java:114)    
  at com.sun.proxy.$Proxy6.executeQuery(Unknown Source)    
  ...

通過提示信息,可以看到 "Statement cancelled due to timeout or client request",表示 sql 由于執(zhí)行超時而被取消了。

通過statement timeout,我們可以更加靈活的為不同的sql設(shè)置不同的超時時間。

但是,需要注意的是,盡管statement timeout很靈活,但是在高并發(fā)的情況下,會創(chuàng)建大量的線程,一些場景下筆者并不建議使用。

原因在于,mysql-connector-java底層是通過定時器Timer來實現(xiàn)statement timeout的功能,也就是說,對于設(shè)置了statement timeout的sql,將會導(dǎo)致mysql創(chuàng)建定時Timer來執(zhí)行sql,意味著高并發(fā)的情況下,mysql驅(qū)動可能會創(chuàng)建大量線程。

通過源碼可以看到,在指定statement timeout的情況下,mysql內(nèi)部會將sql執(zhí)行操作包裝成一個CancelTask,然后通過定時器Timer來運行。

Timer實際上是與ConnectionImpl綁定的,同一個ConnectionImpl執(zhí)行的多個sql,會共用這個Timer。

默認情況下,這個Timer是不會創(chuàng)建的,一旦某個ConnectionImpl上執(zhí)行的一個sql,指定了statement timeout,此時這個Timer才創(chuàng)建,一直到這個ConnectionImpl被銷毀時,Timer才會取消。

在一些場景下,如分庫分表、讀寫分離,如果使用的數(shù)據(jù)庫中間件是基于smart-client方式實現(xiàn)的,會與很多庫建立連接,由于其底層最終也是通過mysql-connector-java創(chuàng)建連接,這種場景下,如果指定了statement timeout,那么應(yīng)用中將會存在大量的Timer線程,在這種場景下,并不建議設(shè)置。

最后,需要提醒的是,socket timeout是TCP層面的超時,是操作系統(tǒng)層面進行的控制,statement timeout是驅(qū)動層面實現(xiàn)的超時,是應(yīng)用層面進行的控制,如果同時設(shè)置了二者,那么后者必須比前者大,否則statement timeout無法生效。

當(dāng)拋出異常后,調(diào)用 conn.isClosed() 返回 false。 

4、事務(wù)執(zhí)行超時設(shè)置

前面提到的的socket timeout、statement timeout,都是限制單個sql的最大執(zhí)行超時。

在事務(wù)的情況下,可能需要執(zhí)行多個sql,我們想針對整個事務(wù)設(shè)置一個最大的超時時間。

例如,我們在采用spring配置事務(wù)管理器的時候,可以指定一個defaultTimeout屬性,單位是秒,指定所有事務(wù)的默認超時時間。

在 spring 中,通過在 @Transactional 注解上針對某個事務(wù),指定超時時間,如:

@Transactional(timeout = 3)

transaction timeout的實現(xiàn)原理可以用以下流程進行描述,假設(shè)事務(wù)超時為5秒,需要執(zhí)行3個sql:

?start transaction ?
?#事務(wù)超時為5秒
?
?sql1 ?
?#statement timeout設(shè)置為5秒
?#執(zhí)行耗時1s,那么整個事務(wù)超時還剩4秒
?
?sql2
?#設(shè)置statement timeout設(shè)置為4秒
?#執(zhí)行耗時2秒,整個事務(wù)超時還是2秒
?
?sql3 ?
?#設(shè)置statement timeout設(shè)置為2秒
?#假設(shè)執(zhí)行耗時超過2s,那么整個事務(wù)超時,拋出異常 ?

這里只是一個簡化的流程,但是可以幫助我們了解spring事務(wù)超時的原理。

從這個流程中,我們可以看到,spring事務(wù)的超時機制,實際上是還是通過Statement.setQueryTimeout進行設(shè)置,每次都是把當(dāng)前事務(wù)的剩余時間,設(shè)置到下一個要執(zhí)行的sql中。

事實上,spring的事務(wù)超時機制,需要ORM框架進行支持,例如mybatis-spring提供了一個SpringManagedTransaction,里面有一個getTimeout方法,就是通過從spring中獲取事務(wù)的剩余時間。

當(dāng)拋出異常后,調(diào)用 conn.isClosed() 返回 false。 

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 在MySQL中實現(xiàn)基于時間點的數(shù)據(jù)恢復(fù)

    在MySQL中實現(xiàn)基于時間點的數(shù)據(jù)恢復(fù)

    在MySQL中實現(xiàn)基于時間點的數(shù)據(jù)恢復(fù)是一個復(fù)雜但可行的過程,主要依賴于MySQL的二進制日志(Binary Log),本文介紹了實現(xiàn)此功能的一般步驟,并有詳細的代碼供大家參考,需要的朋友可以參考下
    2024-03-03
  • MySQL慢查詢診斷與SQL注入防御詳解

    MySQL慢查詢診斷與SQL注入防御詳解

    本文介紹MySQL慢查詢診斷與SQL注入防御的相關(guān)知識,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2026-04-04
  • MySQL8.0?索引優(yōu)化invisible?index詳情

    MySQL8.0?索引優(yōu)化invisible?index詳情

    這篇文章主要介紹了MySQL8.0?索引優(yōu)化invisible?index詳情,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09
  • Mysql刪除重復(fù)的數(shù)據(jù) Mysql數(shù)據(jù)去重復(fù)

    Mysql刪除重復(fù)的數(shù)據(jù) Mysql數(shù)據(jù)去重復(fù)

    這篇文章主要介紹了Mysql刪除重復(fù)的數(shù)據(jù) Mysql數(shù)據(jù)去重復(fù),需要的朋友可以參考下
    2016-08-08
  • MySQL之導(dǎo)出整個及單個表數(shù)據(jù)的操作

    MySQL之導(dǎo)出整個及單個表數(shù)據(jù)的操作

    這篇文章主要介紹了MySQL之導(dǎo)出整個及單個表數(shù)據(jù)的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • MySQL 5.7 學(xué)習(xí)心得之安全相關(guān)特性

    MySQL 5.7 學(xué)習(xí)心得之安全相關(guān)特性

    這篇文章主要介紹了MySQL 5.7 學(xué)習(xí)心得之安全相關(guān)特性 的相關(guān)資料,需要的朋友可以參考下
    2016-07-07
  • MySQL在grant時報錯ERROR?1064?(42000)的原因及解決方法

    MySQL在grant時報錯ERROR?1064?(42000)的原因及解決方法

    網(wǎng)上查到的grant方式大多會報錯,主要原因是MySQL版本8.0后不能再使用原來的方式,這篇文章主要介紹了MySQL在grant時報錯ERROR?1064?(42000),需要的朋友可以參考下
    2022-08-08
  • mysql之DML的select分組排序方式

    mysql之DML的select分組排序方式

    在此教程中,我們詳細介紹如何創(chuàng)建員工(employee)和部門(department)數(shù)據(jù)庫表,并展示了如何通過SQL語句進行數(shù)據(jù)插入、刪除和查詢,首先,創(chuàng)建了部門表并自動設(shè)置部門編號起始值為1001,接著創(chuàng)建員工表并定義了各字段,我們還設(shè)置了外鍵關(guān)聯(lián)兩表
    2024-09-09
  • Mysql百萬級分頁優(yōu)化技巧

    Mysql百萬級分頁優(yōu)化技巧

    這篇文章主要介紹了Mysql百萬級分頁優(yōu)化技巧,包括普通分頁和優(yōu)化分頁兩種,在數(shù)據(jù)量比較大的時候,我們盡量去利用索引來優(yōu)化語句。下面通過本文給大家詳細講解,一起看看吧
    2016-12-12
  • Linux下MySql 1036 錯誤碼解決(1036: Table ''xxxx'' is read only)

    Linux下MySql 1036 錯誤碼解決(1036: Table ''xxxx'' is read only)

    我們在進行數(shù)據(jù)庫搬家的時候,經(jīng)常會遇到(1036: Table 'xxxx' is read only)的問題,字面意思很明確,就是數(shù)據(jù)庫只有讀權(quán)限,無寫權(quán)限,那么我們來分享下我的處理辦法
    2014-07-07

最新評論

大冶市| 滨州市| 浙江省| 偃师市| 永福县| 游戏| 开化县| 华阴市| 柘荣县| 苏尼特右旗| 福海县| 浑源县| 新闻| 贵定县| 松溪县| 桂东县| 旬阳县| 德庆县| 诸暨市| 新竹市| 云阳县| 罗平县| 阿合奇县| 孟村| 思茅市| 凌海市| 孝义市| 日照市| 桐庐县| 上饶县| 江达县| 定陶县| 老河口市| 长顺县| 拉孜县| 乌拉特中旗| 逊克县| 浙江省| 繁峙县| 如皋市| 清水河县|