1. 程式人生 > >利用C3P0連線池連線mysql資料庫,超過幾小時後連線報wait_timeout錯誤

利用C3P0連線池連線mysql資料庫,超過幾小時後連線報wait_timeout錯誤

之前做了一個小專案,用的是C3P0連線池連線mysql資料庫,由於連線數目較小,隔天再連線發現報如下異常錯誤,然後重新重新整理後又正常:

之後檢視資料後發現是因為 :MySQL 的預設設定下,當一個連線的空閒時間超過8小時後,MySQL 就會斷開該連線,而 c3p0 連線池則以為該被斷開的連線依然有效。在這種情況下,如果客戶端程式碼向 c3p0 連線池請求連線的話,連線池就會把已經失效的連線返回給客戶端,客戶端在使用該失效連線的時候即丟擲異常。

解決辦法有三種:

解決的方法有3種:

  1. 增加wait_timeout的時間。
  2. 減少Connection pools中connection的lifetime。
  3. 測試Connection pools中connection的有效性。
當然最好三種都調整:

1、增加 MySQL 的 wait_timeout 屬性的值,將這2個引數設定為24小時(60*60*24=604800)即可。
set interactive_timeout=604800;
set wait_timeout=604800;

2、

        <property name="testConnectionOnCheckin">true</property>
        <property name="automaticTestTable">C3P0TestTable</property>
        <property name="idleConnectionTestPeriod">18000</property>
        <property name="maxIdleTime">25000</property>
        <property name="testConnectionOnChectout">true</property>

下面奉上C3P0詳細配置,供大家參考:

<c3p0-config>
<default-config>
<!--當連線池中的連線耗盡的時候c3p0一次同時獲取的連線數。Default: 3 -->
<property name="acquireIncrement">3</property>

<!--定義在從資料庫獲取新連線失敗後重復嘗試的次數。Default: 30 -->
<property name="acquireRetryAttempts">30</property>

<!--兩次連線中間隔時間,單位毫秒。Default: 1000 -->
<property name="acquireRetryDelay">1000</property>

<!--連線關閉時預設將所有未提交的操作回滾。Default: false -->
<property name="autoCommitOnClose">false</property>

<!--c3p0將建一張名為Test的空表,並使用其自帶的查詢語句進行測試。如果定義了這個引數那麼
屬性preferredTestQuery將被忽略。你不能在這張Test表上進行任何操作,它將只供c3p0測試
使用。Default: null-->
<property name="automaticTestTable">Test</property>

<!--獲取連線失敗將會引起所有等待連線池來獲取連線的執行緒丟擲異常。但是資料來源仍有效
保留,並在下次呼叫getConnection()的時候繼續嘗試獲取連線。如果設為true,那麼在嘗試
獲取連線失敗後該資料來源將申明已斷開並永久關閉。Default: false-->
<property name="breakAfterAcquireFailure">false</property>

<!--當連線池用完時客戶端呼叫getConnection()後等待獲取新連線的時間,超時後將丟擲
SQLException,如設為0則無限期等待。單位毫秒。Default: 0 -->
<property name="checkoutTimeout">100</property>

<!--通過實現ConnectionTester或QueryConnectionTester的類來測試連線。類名需制定全路徑。
Default: com.mchange.v2.c3p0.impl.DefaultConnectionTester-->
<property name="connectionTesterClassName"></property>

<!--指定c3p0 libraries的路徑,如果(通常都是這樣)在本地即可獲得那麼無需設定,預設null即可
Default: null-->
<property name="factoryClassLocation">null</property>

<!--Strongly disrecommended. Setting this to true may lead to subtle and bizarre bugs.
(文件原文)作者強烈建議不使用的一個屬性-->
<property name="forceIgnoreUnresolvedTransactions">false</property>

<!--每60秒檢查所有連線池中的空閒連線。Default: 0 -->
<property name="idleConnectionTestPeriod">60</property>

<!--初始化時獲取三個連線,取值應在minPoolSize與maxPoolSize之間。Default: 3 -->
<property name="initialPoolSize">3</property>

<!--最大空閒時間,60秒內未使用則連線被丟棄。若為0則永不丟棄。Default: 0 -->
<property name="maxIdleTime">60</property>

<!--連線池中保留的最大連線數。Default: 15 -->
<property name="maxPoolSize">15</property>

<!--JDBC的標準引數,用以控制資料來源內載入的PreparedStatements數量。但由於預快取的statements
屬於單個connection而不是整個連線池。所以設定這個引數需要考慮到多方面的因素。
如果maxStatements與maxStatementsPerConnection均為0,則快取被關閉。Default: 0-->
<property name="maxStatements">100</property>

<!--maxStatementsPerConnection定義了連線池內單個連線所擁有的最大快取statements數。Default: 0 -->
<property name="maxStatementsPerConnection"></property>

<!--c3p0是非同步操作的,緩慢的JDBC操作通過幫助程序完成。擴充套件這些操作可以有效的提升效能
通過多執行緒實現多個操作同時被執行。Default: 3-->
<property name="numHelperThreads">3</property>

<!--當用戶呼叫getConnection()時使root使用者成為去獲取連線的使用者。主要用於連線池連線非c3p0
的資料來源時。Default: null-->
<property name="overrideDefaultUser">root</property>

<!--與overrideDefaultUser引數對應使用的一個引數。Default: null-->
<property name="overrideDefaultPassword">password</property>

<!--密碼。Default: null-->
<property name="password"></property>

<!--定義所有連線測試都執行的測試語句。在使用連線測試的情況下這個一顯著提高測試速度。注意:
測試的表必須在初始資料來源的時候就存在。Default: null-->
<property name="preferredTestQuery">select id from test where id=1</property>

<!--使用者修改系統配置引數執行前最多等待300秒。Default: 300 -->
<property name="propertyCycle">300</property>

<!--因效能消耗大請只在需要的時候使用它。如果設為true那麼在每個connection提交的
時候都將校驗其有效性。建議使用idleConnectionTestPeriod或automaticTestTable
等方法來提升連線測試的效能。Default: false -->
<property name="testConnectionOnCheckout">false</property>

<!--如果設為true那麼在取得連線的同時將校驗連線的有效性。Default: false -->
<property name="testConnectionOnCheckin">true</property>

<!--使用者名稱。Default: null-->
<property name="user">root</property>

<!--早期的c3p0版本對JDBC介面採用動態反射代理。在早期版本用途廣泛的情況下這個引數
允許使用者恢復到動態反射代理以解決不穩定的故障。最新的非反射代理更快並且已經開始
廣泛的被使用,所以這個引數未必有用。現在原先的動態反射與新的非反射代理同時受到
支援,但今後可能的版本可能不支援動態反射代理。Default: false-->
<property name="usesTraditionalReflectiveProxies">false</property>

<property name="automaticTestTable">con_test</property>
<property name="checkoutTimeout">30000</property>
<property name="idleConnectionTestPeriod">30</property>
<property name="initialPoolSize">10</property>
<property name="maxIdleTime">30</property>
<property name="maxPoolSize">25</property>
<property name="minPoolSize">10</property>
<property name="maxStatements">0</property>
<user-overrides user="swaldman">
</user-overrides>
</default-config>
<named-config name="dumbTestConfig">
<property name="maxStatements">200</property>
<user-overrides user="poop">
<property name="maxStatements">300</property>
</user-overrides>
</named-config>
</c3p0-config>