事務超時Transaction Timeout
事務超時時間規定了事務執行時間的上限,通常包含兩大部分:SQL執行時間,以及業務處理時間,即Transaction timeout = Statement Timeout * N(所有SQL執行總時間) + 業務處理時間;
@Transactional(timeout = 3) 單位秒
事務超時的報錯信息:
org.springframework.transaction.TransactionTimedOutException: Transaction timed out: deadline was Wed Apr 24 10:54:36 CST 2019
造成事務超時的可能原因:
- 超時時間過小;
- SQL或者業務處理時間過長;
SQL超時Statement Timeout
SQL超時時間規定了SQL執行時間的上限,現在很多框架都提供了參數設置,最終都會都調用JDBC的java.sql.Statement.setQueryTimeout(int timeout) API進行設置;
SQL執行超時報錯信息:
com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction
Mybatis設置
全局默認設置:Mybatis配置文件中設置SQL默認超時時間,單位秒,如下:
<setting name="defaultStatementTimeout" value=“5”/>
單條SQL設置:設置sqlmap中select,insert,update標籤的timeout屬性,如下:
<delete id="deleteByPrimaryKey" parameterType="java.lang.Long" timeout="4">
delete from task_def
where id = #{id,jdbcType=BIGINT}
</delete>
Druid設置
設置queryTimeout和transactionQueryTimeout屬性;
JDBC連接超時Socket Timeout
JDBC連接超時包含三種含義:
- 與數據庫建立連接超時:通過Socket.connect(SocketAddress endpoint, int timeout)設置;
- 連接讀寫超時:通過Socket.setSoTimeout(int timeout)設置;
- 從連接池獲取連接超時:通過連接池參數設置;
不推薦使用socket timeout來限制statement的執行時長,因此socket timeout的值必須要高於statement timeout,否則,socket timeout將會先生效,這樣statement timeout就變得毫無意義,也無法生效,設置方式如下:
數據庫服務端超時設置
//查看數據庫服務端所有超時配置
show variables like '%timeout%';
- connect_timeout:建立連接超時時間,默認10s;
- wait_timeout/interactive_timeout:連接空閒(sleep狀態)超時時間,超過設定時間服務端會主動斷開連接,默認8小時;
- net_read_timeout:連接讀超時時間;
- net_write_timeout:連接寫超時時間;
- innodb_lock_wait_timeout:事務獲取行鎖等待超時時間,單位s,默認50s;
show variables like '%innodb_lock_wait_timeout%';
- lock_wait_timeout:事務獲取元數據相關鎖等待超時時間;
This variable specifies the timeout in seconds for attempts to acquire metadata locks.
參考: