1. 程式人生 > >MySql資料庫連線超時處理

MySql資料庫連線超時處理

博主在做web開發時遇到MySql資料庫連線超時的問題。

控制檯報錯如下:

Request processing failed; nested exception is org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure Last packet sent to the server was 1 ms ago.

由於用到了spring+mybatis的框架,剛開始以為是mybatis引起的,後來才發現是MySql資料庫連線超時。

這個異常是由於MySQL服務再長時間不連線之後斷開了,斷開之後的首次請求會丟擲異常。那麼既然是超時問題,就要去探究一下Mysql連線時間是怎麼控制的。開啟Mysql的控制檯,執行:show variables like '%timeout%'; ,檢視和連線時間有關的Mysql系統變數,如圖:


其中wait_timeout就是負責超時控制的遍歷,其時間為長度28800s,就是8個小時,那麼就是說Mysql的服務會在操作間隔8小時後斷開,需要再次重連。

interactive_timeout:伺服器關閉互動式連線前等待活動的秒數。互動式客戶端定義為在mysql_real_connect()中使用CLIENT_INTERACTIVE選項的客戶端。

    wait_timeout:伺服器關閉非互動連線之前等待活動的秒數。線上程啟動時,根據全域性wait_timeout值或全域性interactive_timeout值初始化會話wait_timeout值,取決於客戶端型別(由mysql_real_connect()的連線選項CLIENT_INTERACTIVE定義)。

    如此看來,兩個變數是共同控制的,那麼都必須對他們進行修改了。繼續深入這兩個變數wait_timeout的取值範圍是1-2147483(Windows),1-31536000(linux),interactive_time取值隨wait_timeout變動,它們的預設值都是28800。

Mysql的系統變數由配置檔案控制,當配置檔案中不配置時,系統使用預設值,這個28800就是預設值。Linux系統下的配置檔案為/etc/my.cnf,windows下在[MySQL_HOME]/bin下的mysql.ini。

修改之後儲存退出,重啟mysql服務。

如果不修改mysql的配置,需要直接在spring-mybatis的配置檔案中實現,可以採用以下的方式:

	<bean id="mysql" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
		<property name="driverClassName" 	value="${mysql_driver}"/>
		<property name="url" 		value="${mysql_url}"/>
		<property name="username" 	value="${mysql_username}"/>
		<property name="password" 	value="${mysql_password}"/>
		<property name="validationQuery" 	value="SELECT 1"/>
		<property name="testOnBorrow" 		value="true"/>
	</bean>
如上面程式碼所示,dirverClassName,url,username,password是資料庫的連線配置,都很常見。關鍵是validationQuery和testOnBorrow兩個引數。Spring建議使用的資料來源有Apache的DBCP和C3P0,這裡使用的是DBCP,前面四個引數是基本引數,而後面兩個引數是連線健康情況的引數,如下圖所示:

添加了validationQuery和testOnBorrow兩個引數可以保證在mysql服務長時間不連線斷開之後的請求不會出現異常情況,當然也可以在配置檔案中將testOnReturn等之類的配置加上。