天天看點

資料庫連接配接池碰到mysql的wait_timeout出現連接配接異常的解決問題

項目最近老是在重新開機8小時候過後查詢出錯。check log,發現是mysql資料庫預設wait_time時間是8小時。8小時候過後,datasource-pool中的所有連接配接被mysql-server端釋放掉。用戶端并不知道,程式直接從datasource-pool中擷取連接配接,并沒有檢測連接配接有效性,使用的時候就出錯了。

于是就趁此機會,花了兩天時間仔細學習了mysql的相關設定和dbcp和c3p0。

由于要測試,肯定不能用mysql預設的8小時來測試了。等的頭發都白了,還不能重制。果斷重設wait_time時間。mysql 上有段原話

The number of seconds the server waits for activity on a noninteractive connection before closing it. This timeout applies only to TCP/IP and Unix socket file connections, not to connections made using named pipes, or shared memory.

這個數值隻對tcp/ip和unix socket 連接配接有效,對命名管道,和共享記憶體無效。 mysql的驅動建立的連接配接是tcp/ip連接配接吧,果斷繼續。

然後官網上又說wait_timeout的初始值是從全局wait_timeout和 interactive_timeout.初始化來的。

果斷設定全局wait_timeout。 狂百度,大家都說在my.cnf中設定,重新開機。好吧,my.cnf中設定好,重新開機mysql。show variables like '%timeout',成功了,但是測試發現沒起作用。怎麼一回事?百度,就那點貨了,找不到。然後還是google。 原來是my.cnf設定的也是session級别的。對mysql驅動建立的連接配接沒起作用,這裡我也不明白為什麼沒起作用,有人知道,可以知會一聲,難道mysql驅動建立的連接配接不是session級别麼。 show gloable variables like '%timeout%'。還是預設值。也就是my.cnf設定這種方式是不成功的,直接set globle wait_timeout=10.--Query OK, 0 rows affected (0.00 sec。 怎麼回事,沒成功?再次show一下。原來已經成功了。 再次測試驗證,wait_timeout已經設定成功。

這裡為了解決問題,其實我是知道建立測試query和測試表是可以實作的。但是後來又聽說連接配接屬性設定autoReconnect=true也可以。設定過後,就像其他人一樣,java的mysql驅動是不行的。autoReconnect 和autoReconnectForPool 都不行,四處查詢了下。這個參數不适用java的mysql驅動。罷了,還是老老實實的設定validatequery吧。

這裡項目中都引入了dbcpjar包和c3p0jar包,配置哪一種資料庫連接配接池都可以。

dbcp: 必須設定validateQuery testOnBorrow也要設定為true。testWhileIdle設定為true也行。再次測試,其實就設定了個validateQuery也行。其他參數不要。

隻是這樣實際的pool中不會維持最小數量idle的連接配接。每次獲得新的連接配接的時候驗證連接配接有效性,都失效了了話,重建立立一個。

c3p0:通過idleConnectionTestPeriod和maxIdleTime 這兩個參數的配置,具體就是必須小于mysq server端的wait_time時間設定,可以不用validateQuery testTable等複雜設定就解決mysql的wait_time逾時的問題。

而且本人不鐘愛異步程式。 c3p0不需要額外的validatquery。 不需要額外的表,保持了資料庫的幹淨。 是以就用c3p0