1. 程式人生 > >C3P0連線池+MySQL的配置以及wait_timeout問題的解決

C3P0連線池+MySQL的配置以及wait_timeout問題的解決

一、配置環境

spring4.2.4+mybatis3.2.8+c3p0-0.9.1.2+Mysql5.6.24

二、c3p0的配置詳解及spring+c3p0配置

1.配置詳解

<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>

2.spring+mybatis+c3p0的基本配置

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
		<property name="driverClass" value="${jdbc.driver}"/>
		<property name="jdbcUrl" value="${jdbc.url}"/>
		<property name="user" value="${jdbc.user}"/>
		<property name="password" value="${jdbc.password}"/>	
</bean>


初始化基本配置資訊如下:

Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 1hge26l9jv0ov961czeg8w|a2f51c, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 1hge26l9jv0ov961czeg8w|a2f51c, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:mysql://192.168.6.24:3306/ETeam, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 15, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ]


三、遇到的問題:

1.問題log:

嚴重: Servlet.service() for servlet [ETeam] in context with path [/ETeam] threw exception [Request processing failed; nested exception is org.springframework.dao.RecoverableDataAccessException: 
### Error querying database.  Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 55,518,630 milliseconds ago.  The last packet sent successfully to the server was 55,518,631 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.
### The error may exist in com/mango/mapper/ProductMapper.java (best guess)
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: SELECT * FROM product
### Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 55,518,630 milliseconds ago.  The last packet sent successfully to the server was 55,518,631 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.
; SQL []; The last packet successfully received from the server was 55,518,630 milliseconds ago.  The last packet sent successfully to the server was 55,518,631 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.; nested exception is com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 55,518,630 milliseconds ago.  The last packet sent successfully to the server was 55,518,631 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.] with root cause
java.net.SocketException: Connection reset by peer: socket write error
	at java.net.SocketOutputStream.socketWrite0(Native Method)
	at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:113)
	at java.net.SocketOutputStream.write(SocketOutputStream.java:159)
	at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
	at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
	at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3634)
	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2460)
	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2625)
	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2551)
	at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861)
	at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1192)
	at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.execute(NewProxyPreparedStatement.java:989)
	at sun.reflect.GeneratedMethodAccessor46.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:62)
	at com.sun.proxy.$Proxy138.execute(Unknown Source)
	at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:59)
	at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:73)
	at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:60)
	at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:267)
	at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:137)
	at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:96)
	at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:77)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:108)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:102)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:358)
	at com.sun.proxy.$Proxy357.selectList(Unknown Source)
	at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:198)
	at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:119)
	at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:63)
	at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:52)
	at com.sun.proxy.$Proxy376.getProductIndex(Unknown Source)
	at com.mango.service.impl.ProductServiceImpl.getProductIndex(ProductServiceImpl.java:25)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:280)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
	at com.sun.proxy.$Proxy377.getProductIndex(Unknown Source)
	at com.mango.controller.PageController.index(PageController.java:57)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:814)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:737)

	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:969)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:860)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:845)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at com.mango.filter.BaseFilter.doFilter(BaseFilter.java:34)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317)
	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
	at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
	at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
	at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
	at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
	at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:158)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:121)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
	at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
	at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
	at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:134)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.sitemesh.webapp.contentfilter.ContentBufferingFilter.bufferAndPostProcess(ContentBufferingFilter.java:169)
	at org.sitemesh.webapp.contentfilter.ContentBufferingFilter.doFilter(ContentBufferingFilter.java:126)
	at org.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:120)
	at org.sitemesh.config.ConfigurableSiteMeshFilter.doFilter(ConfigurableSiteMeshFilter.java:163)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
	at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1813)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at java.lang.Thread.run(Thread.java:745)


從問題log中

The last packet successfully received from the server was 55,518,630 milliseconds ago.  The last packet sent successfully to the server was 55,518,631 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.; nested exception is com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 55,518,630 milliseconds ago.  The last packet sent successfully to the server was 55,518,631 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.] with root cause

很容易看出是由於wait_timeout(伺服器關閉非互動連線之前等待活動的秒數)造成的。mysql會根據wait_timeout設定每個空閒連線的超時時間,時間到了就會斷開。

2.檢視mysql的wait_timeout

mysql> show global variables like 'wait_timeout';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout  | 28800 |
+---------------+-------+
1 row in set

預設設定28800秒,即8小時,明顯連線時間55,518,630 milliseconds超過了mysql資料庫設定的wait_timeout

修改命令:mysql>set global wait_timeout=28800;  

3.問題解決

1)log中也給瞭解決方案:

You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.
你應該考慮到期和/或有效性測試連線在應用程式中使用之前,增加伺服器為客戶機超時配置值,或使用聯結器/ J連線屬性“autoReconnect = true”來避免這個問題。

2)後兩種方法顯然不太實用

增加mysql資料庫的超時時間,由於最大超時時間是2147483一年,不可無限制增加,再說也不應該隨便增加。'autoReconnect=true'如果使用的時候reconnect會影響效率,而且據說mysql5以上無效(本人沒試),而且官方也不建議http://bugs.mysql.com/bug.php?id=5020

3)採用c3p0提供的方案

The most reliable time to test Connections is on check-out. But this is also the most costly choice from a client-performance perspective. Most applications should work quite reliably using a combination of idleConnectionTestPeriod and testConnectionOnCheckin. Both the idle test and the check-in test are performed asynchronously, which can lead to better performance, both perceived and actual. 

For some applications, high performance is more important than the risk of an occasional database exception. In its default configuration, c3p0 does no Connection testing at all. Setting a fairly long idleConnectionTestPeriod, and not testing on checkout and check-in at all is an excellent, high-performance approach. 

 最可靠的是退出時間測試連線。但這也是最昂貴的從客戶端效能的角度選擇。大多數應用程式應該使用idleConnectionTestPeriod和testConnectionOnCheckin相當可靠。閒置的測試和登記測試是非同步執行的,這可能導致更好的效能,感知和實際。

對於某些應用程式,高效能比偶爾的風險更重要資料庫異常。在預設配置中,c3p0沒有連線測試。設定一個相當長的idleConnectionTestPeriod,而不是測試是一個很好的檢驗和登記,高效能的方法。

考慮再三可以如下設定

設定c3p0中連線池內連線的生存週期(idleConnectionTestPeriod)小於資料庫中的wait_timeout的值

<!--每5小時檢查所有連線池中的空閒連線。防止mysql wait_timeout(預設的為8小時) -->
		<property name="idleConnectionTestPeriod" value="18000"/>



四、c3p0中用到的定時任務是java中的Timer實現的,實際上是TimerThread的定時執行

checkidle原始碼

BasicResourcePool.java 
// this is run by a single-threaded timer, so we don't have
    // to worry about multiple threads executing the task at the same 
    // time 
    class CheckIdleResourcesTask extends TimerTask
    {
        public void run()
        {
            try
            {
                //System.err.println("c3p0-JENNIFER: refurbishing idle resources - " + new Date() + " [" + BasicResourcePool.this + "]");
                if (Debug.DEBUG && Debug.TRACE >= Debug.TRACE_MED && logger.isLoggable(MLevel.FINER))
                    logger.log(MLevel.FINER, "Refurbishing idle resources - " + new Date() + " [" + BasicResourcePool.this + "]");
                synchronized ( BasicResourcePool.this )
                { checkIdleResources(); }
            }
            catch ( ResourceClosedException e ) // one of our async threads died
            {
                //e.printStackTrace();
                if ( Debug.DEBUG )
                {
                    if ( logger.isLoggable( MLevel.FINE ) )
                        logger.log( MLevel.FINE, "a resource pool async thread died.", e );
                }
                unexpectedBreak();
            }
        }
    }

最終測試:

C3P0PooledConnectionPool.java
private void testPooledConnection(Object resc) throws Exception
                { 
                    PooledConnection pc = (PooledConnection) resc;

                    Throwable[] throwableHolder = EMPTY_THROWABLE_HOLDER;
                    int status;
                    Connection conn = null;
                    Throwable rootCause = null;
                    try	
                    { 
                        //we don't want any callbacks while we're testing the resource
                        pc.removeConnectionEventListener( cl );

                        conn = pc.getConnection(); //checkout proxy connection

                        // if this is a c3p0 pooled-connection, let's get underneath the
                        // proxy wrapper, and test the physical connection sometimes. 
                        // this is faster, when the testQuery would not otherwise be cached,
                        // and it avoids a potential statusOnException() double-check by the
                        // PooledConnection implementation should the test query provoke an
                        // Exception
                        Connection testConn;
                        if (scache != null) //when there is a statement cache...
                        {
                            // if it's the slow, default query, faster to test the raw Connection 
                            if (testQuery == null && connectionTesterIsDefault && c3p0PooledConnections)
                                testConn = ((AbstractC3P0PooledConnection) pc).getPhysicalConnection();
                            else //test will likely be faster on the proxied Connection, because the test query is probably cached
                                testConn = conn; 
                        }
                        else //where there's no statement cache, better to use the physical connection, if we can get it
                        {
                            if (c3p0PooledConnections)
                                testConn = ((AbstractC3P0PooledConnection) pc).getPhysicalConnection();
                            else    
                                testConn = conn;
                        }

                        if ( testQuery == null )
                            status = connectionTester.activeCheckConnection( testConn );
                        else
                        {
                            if (connectionTester instanceof UnifiedConnectionTester)
                            {
                                throwableHolder = thp.getThrowableHolder();
                                status = ((UnifiedConnectionTester) connectionTester).activeCheckConnection( testConn, testQuery, throwableHolder );
                            }
                            else if (connectionTester instanceof QueryConnectionTester)
                                status = ((QueryConnectionTester) connectionTester).activeCheckConnection( testConn, testQuery );
                            else
                            {
                                // System.err.println("[c3p0] WARNING: testQuery '" + testQuery +
                                // "' ignored. Please set a ConnectionTester that implements " +
                                // "com.mchange.v2.c3p0.advanced.QueryConnectionTester, or use the " +
                                // "DefaultConnectionTester, to test with the testQuery.");

                                logger.warning("[c3p0] testQuery '" + testQuery +
                                                "' ignored. Please set a ConnectionTester that implements " +
                                                "com.mchange.v2.c3p0.QueryConnectionTester, or use the " +
                                "DefaultConnectionTester, to test with the testQuery.");
                                status = connectionTester.activeCheckConnection( testConn );
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        if (Debug.DEBUG)
                            logger.log(MLevel.FINE, "A Connection test failed with an Exception.", e);
                        //e.printStackTrace();
                        status = ConnectionTester.CONNECTION_IS_INVALID;
//                      System.err.println("rootCause ------>");
//                      e.printStackTrace();
                        rootCause = e;
                    }
                    finally
                    { 
                        if (rootCause == null)
                            rootCause = throwableHolder[0];
                        else if (throwableHolder[0] != null && logger.isLoggable(MLevel.FINE))
                            logger.log(MLevel.FINE, "Internal Connection Test Exception", throwableHolder[0]);
                        
                        if (throwableHolder != EMPTY_THROWABLE_HOLDER)
                            thp.returnThrowableHolder( throwableHolder );
                        
                        ConnectionUtils.attemptClose( conn ); //invalidate proxy connection
                        pc.addConnectionEventListener( cl );  //should we move this to CONNECTION_IS_OKAY case? (it should work either way)
                    }

                    switch (status)
                    {
                    case ConnectionTester.CONNECTION_IS_OKAY:
                        break; //no problem, babe
                    case ConnectionTester.DATABASE_IS_INVALID:
                        rp.resetPool();
                        //intentional cascade...
                    case ConnectionTester.CONNECTION_IS_INVALID:
                        Exception throwMe;
                        if (rootCause == null)
                            throwMe = new SQLException("Connection is invalid");
                        else
                            throwMe = SqlUtils.toSQLException("Connection is invalid", rootCause);
                        throw throwMe;
                    default:
                        throw new Error("Bad Connection Tester (" + 
                                        connectionTester + ") " +
                                        "returned invalid status (" + status + ").");
                    }
                }


     

相關推薦

C3P0連線+MySQL配置以及wait_timeout問題的解決

一、配置環境 spring4.2.4+mybatis3.2.8+c3p0-0.9.1.2+Mysql5.6.24 二、c3p0的配置詳解及spring+c3p0配置 1.配置詳解 <c3p0-config> < default-config>&l

Java程式中insert 執行慢的原因,以及c3p0連線配置

今天遇到一個問題,程式中一個insert 操作特別慢, 一直從來沒有遇到過,select 操作如果資料量大的話,是有可能出現這種情況的,但是單條insert插入操作出現這種情況,不知道從何查原因了,debug了確定了就是insert這個操作慢,一開始分析是不是mysql原因,在Navicat上ins

c3p0連線xml配置檔案報錯的處理

有下劃線並提示 The word is not correctly spelled, 此問題是Eclipse校驗單詞拼寫造成的。 解決辦法如下:   Window--Preference輸入spell,然後把第一個複選框“Enable spell checking“去掉對勾就

tomcat自帶連線dbcp配置以及優化說明

轉自:http://www.totcms.com/html/201602-29/20160229114145.htm 一個網站每天大概有20萬的訪問量,使用的tomcat自帶dbcp連線池,一般網站訪問很好,速度也很快,但是過一段時間後,總是報timeout waiting for idl

C3P0連線詳細配置(轉載)

 C3P0連線池詳細配置 <c3p0-config>  <default-config>  <!--當連線池中的連線耗盡的時候c3p0一次同時獲取的連線數。Default: 3 -->  <property name=

c3p0連線配置檔案方式)

package Test02; import com.mchange.v2.c3p0.ComboPooledDataSource; import org.junit.Test; /* 步驟: 1.導包(c3p0-0.9.1.2.jar)+(mysql

C3P0連線配置C3P0在高併發加壓下,響應時間會變成長。

1、C3p0的使用 init.properties 中的配置 #*******************************連線資料配置引數******************************************************* datasource

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

之前做了一個小專案,用的是C3P0連線池連線mysql資料庫,由於連線數目較小,隔天再連線發現報如下異常錯誤,然後重新重新整理後又正常: 之後檢視資料後發現是因為 :MySQL 的預設設定下,當一個連線的空閒時間超過8小時後,MySQL 就會斷開該連線,而 c3p0 連線

用idea配置c3p0連線

文章目錄 前言 1. 準備 2. c3p0連線池配置 新增依賴 建立c3p0-config.xml 3. JDBC連線 4. 測試 5. 小結 前言 上次利用c3p0封裝了資料庫操作工具

spring jdbc --注:c3p0資料庫連線或druid連線使用配置整理

是Maven配置檔案:pom.xml的程式碼內容: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:sch

(mysql版)德魯伊連線配置方法

Mysql的連線池配置方法 先去下載兩個包,匯入bin中百度網盤連結,密碼:n3en 在javaweb專案中的src裡面建立一個字尾為:properties 的File檔案,然後在此檔案頁面中寫下一下程式碼: username=root password

MyBatis配置C3P0連線

這兩天學到Mybatis感覺就要瘋了,第一次接觸,我是不是應該寫點筆記,下面呢,記錄一下連線池的配置,防止忘了。 第一步,二話不說,先匯入所需jar包(如圖所示三個) 第二步,繼承UnpooledDataSourceFactory的類 Mybati

JFinal配置c3p0連線

1.c3p0.properties:連線資料庫 driver=com.mysql.jdbc.Driver jdbcUrl = jdbc:mysql://localhost:3306/test username = root password = root   2.必須定義一個類整合J

SpringBoot多資料來源連線超時配置MySQL+SQLServer)

單資料來源超時配置 spring.datasource.url=jdbc:mysql://127.0.0.1:3306/dcmserver?characterEncoding=utf-8 spring.datasource.username=root spring.data

Hibernate中配置C3P0連線

         Hibernate自帶的連線池演算法相當不成熟。 它只是為了讓你快些上手,並不適合用於產品系統或效能測試中。 出於最佳效能和穩定性考慮你應該使用第三方的連線池。只需要用特定連線池的設定替換 hibernate.connection.pool_size即可。這

Spring通過XML配置c3p0連線和dao層註解注入使用 jdbcTemplate

Spring通過註解配置c3p0連線池和dao使用 jdbcTemplate 1.Spring配置c3p0連線池 第一步:匯入c3p0的jar包 第二步:建立Spring配置檔案,配置連線池 平常我們寫c3p0連線池時是這樣寫的:

Hibernate+Tomcat配置C3P0連線

1.直接配置hibernate.cfg.xml即可 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-conf

資料連線預設配置帶來的坑testOnBorrow=false,cloes_wait 終於解決

首先說一下自己程式中遇到的問題,前一段新寫了一個專案,主要為方便公司業務切庫做準備,為其他專案提供介面(spring boot 專案<spring boot + mongo data jpa+mybatis>) 首先呢 多資料來源沒有使用spring boot 整合mybatis,開始有過自己

JDBC之連線: Tomcat 8.5 MySQL資料庫連線配置與使用

簡介 本文以MySQL資料庫為例,介紹Tomcat 8.5環境下,其預設的資料庫連線池DBCP配置與使用. 連線池簡介 資料庫連線池是在使用者和資料庫之間建立一個”池”,這個池是用來存放資料庫連線物件。回收和重用已存在的資料庫連線比新建一個連線更高效。當用戶想要連線資料庫,

spring+mybatis+c3p0資料庫連線或druid連線使用配置整理

系統性能優化的時候,或者說在進行程式碼開發的時候,多數人應該都知道一個很基本的原則,那就是保證功能正常良好的情況下,要儘量減少對資料庫的操作。  據我所知,原因大概有這樣兩個:  一個是,一般情況下系統伺服器和資料庫伺服器應該是不在同一硬體上,這時候對資料庫的連線