Spring操作資料庫幾十次後就JDBC begin transaction failed
阿新 • • 發佈:2018-11-29
在專案中,有個功能,需要批量操作一批資料,大概要操作近百次。基本上每過120秒就報如下錯誤。修改jdbc的各種連線引數都無效。
15:41:32.701 [http-bio-8081-exec-8] ERROR 500.jsp - Could not open JPA EntityManager for transaction; nested exception is javax.persistence.PersistenceException: org.hibernate.TransactionException: JDBC begin transaction failed: org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is javax.persistence.PersistenceException: org.hibernate.TransactionException: JDBC begin transaction failed: at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:430) ~[spring-orm-4.0.2.RELEASE.jar:4.0.2.RELEASE] at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373) ~[spring-tx-4.0.2.RELEASE.jar:4.0.2.RELEASE] at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:420) ~[spring-tx-4.0.2.RELEASE.jar:4.0.2.RELEASE] at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:257) ~[spring-tx-4.0.2.RELEASE.jar:4.0.2.RELEASE] at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95) ~[spring-tx-4.0.2.RELEASE.jar:4.0.2.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.0.2.RELEASE.jar:4.0.2.RELEASE] at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644) ~[spring-aop-4.0.2.RELEASE.jar:4.0.2.RELEASE] at cn.enetic.wodm.service.ResourceChapterService$$EnhancerBySpringCGLIB$$10162655.saveResourceChapter(<generated>) ~[spring-core-4.0.2.RELEASE.jar:na] at cn.enetic.wodm.web.ResourceChapterController.synsc(ResourceChapterController.java:1207) ~[ResourceChapterController.class:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_144] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_144] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_144] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_144] at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215) ~[spring-web-4.0.2.RELEASE.jar:4.0.2.RELEASE] at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132) ~[spring-web-4.0.2.RELEASE.jar:4.0.2.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) ~[spring-webmvc-4.0.2.RELEASE.jar:4.0.2.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749) ~[spring-webmvc-4.0.2.RELEASE.jar:4.0.2.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:690) ~[spring-webmvc-4.0.2.RELEASE.jar:4.0.2.RELEASE] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83) ~[spring-webmvc-4.0.2.RELEASE.jar:4.0.2.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:945) [spring-webmvc-4.0.2.RELEASE.jar:4.0.2.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:876) [spring-webmvc-4.0.2.RELEASE.jar:4.0.2.RELEASE] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961) [spring-webmvc-4.0.2.RELEASE.jar:4.0.2.RELEASE] at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852) [spring-webmvc-4.0.2.RELEASE.jar:4.0.2.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:620) [servlet-api.jar:na] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837) [spring-webmvc-4.0.2.RELEASE.jar:4.0.2.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) [servlet-api.jar:na] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) [catalina.jar:7.0.53] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.53] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat7-websocket.jar:7.0.53] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.53] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.53] at com.opensymphony.sitemesh.webapp.SiteMeshFilter.obtainContent(SiteMeshFilter.java:129) [sitemesh-2.4.2.jar:na] at com.opensymphony.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:77) [sitemesh-2.4.2.jar:na] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.53] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.53] at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61) [shiro-web-1.2.2.jar:1.2.2] at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108) [shiro-web-1.2.2.jar:1.2.2] at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137) [shiro-web-1.2.2.jar:1.2.2] at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125) [shiro-web-1.2.2.jar:1.2.2] at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66) [shiro-web-1.2.2.jar:1.2.2] at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449) [shiro-web-1.2.2.jar:1.2.2] at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365) [shiro-web-1.2.2.jar:1.2.2] at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90) [shiro-core-1.2.2.jar:1.2.2] at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83) [shiro-core-1.2.2.jar:1.2.2] at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383) [shiro-core-1.2.2.jar:1.2.2] at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362) [shiro-web-1.2.2.jar:1.2.2] at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125) [shiro-web-1.2.2.jar:1.2.2] at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344) [spring-web-4.0.2.RELEASE.jar:4.0.2.RELEASE] at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261) [spring-web-4.0.2.RELEASE.jar:4.0.2.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.53] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.53] at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:177) [spring-orm-4.0.2.RELEASE.jar:4.0.2.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108) [spring-web-4.0.2.RELEASE.jar:4.0.2.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.53] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.53] at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) [spring-web-4.0.2.RELEASE.jar:4.0.2.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108) [spring-web-4.0.2.RELEASE.jar:4.0.2.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.53] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.53] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) [catalina.jar:7.0.53] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) [catalina.jar:7.0.53] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501) [catalina.jar:7.0.53] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170) [catalina.jar:7.0.53] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98) [catalina.jar:7.0.53] at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950) [catalina.jar:7.0.53] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) [catalina.jar:7.0.53] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) [catalina.jar:7.0.53] at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040) [tomcat-coyote.jar:7.0.53] at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607) [tomcat-coyote.jar:7.0.53] at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313) [tomcat-coyote.jar:7.0.53] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_144] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_144] at java.lang.Thread.run(Thread.java:748) [na:1.8.0_144] Caused by: javax.persistence.PersistenceException: org.hibernate.TransactionException: JDBC begin transaction failed: at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1763) ~[hibernate-entitymanager-4.3.1.Final.jar:4.3.1.Final] at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677) ~[hibernate-entitymanager-4.3.1.Final.jar:4.3.1.Final] at org.hibernate.jpa.spi.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:1771) ~[hibernate-entitymanager-4.3.1.Final.jar:4.3.1.Final] at org.hibernate.jpa.internal.TransactionImpl.begin(TransactionImpl.java:64) ~[hibernate-entitymanager-4.3.1.Final.jar:4.3.1.Final] at org.springframework.orm.jpa.DefaultJpaDialect.beginTransaction(DefaultJpaDialect.java:67) ~[spring-orm-4.0.2.RELEASE.jar:4.0.2.RELEASE] at org.springframework.orm.jpa.vendor.HibernateJpaDialect.beginTransaction(HibernateJpaDialect.java:110) ~[spring-orm-4.0.2.RELEASE.jar:4.0.2.RELEASE] at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:380) ~[spring-orm-4.0.2.RELEASE.jar:4.0.2.RELEASE] ... 72 common frames omitted Caused by: org.hibernate.TransactionException: JDBC begin transaction failed: at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:76) ~[hibernate-core-4.3.1.Final.jar:4.3.1.Final] at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:162) ~[hibernate-core-4.3.1.Final.jar:4.3.1.Final] at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1431) ~[hibernate-core-4.3.1.Final.jar:4.3.1.Final] at org.hibernate.jpa.internal.TransactionImpl.begin(TransactionImpl.java:61) ~[hibernate-entitymanager-4.3.1.Final.jar:4.3.1.Final] ... 75 common frames omitted Caused by: java.sql.SQLException: Connection has already been closed. at org.apache.tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.java:117) ~[tomcat-jdbc-7.0.52.jar:na] at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:109) ~[tomcat-jdbc-7.0.52.jar:na] at org.apache.tomcat.jdbc.pool.DisposableConnectionFacade.invoke(DisposableConnectionFacade.java:80) ~[tomcat-jdbc-7.0.52.jar:na] at com.sun.proxy.$Proxy140.getAutoCommit(Unknown Source) ~[na:na] at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:68) ~[hibernate-core-4.3.1.Final.jar:4.3.1.Final] ... 78 common frames omitted
原來採用的是jdbc資料來源
applicationContext.xml
<!-- production環境 --> <beans profile="production"> <context:property-placeholder ignore-unresolvable="true" location="classpath*:/application.properties"/> <!-- 資料來源配置, 使用Tomcat JDBC連線池 --> <bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close"> <!-- Connection Info --> <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <!-- 連線數控制與連線歸還策略 --> <property name="maxActive" value="${jdbc.pool.maxActive}" /> <property name="maxIdle" value="${jdbc.pool.maxIdle}" /> <property name="minIdle" value="${jdbc.pool.minIdle}" /> <property name="maxWait" value="${jdbc.pool.maxWait}" /> <property name="defaultAutoCommit" value="false" /> <!-- 連線Idle一個小時後超時 --> <property name="timeBetweenEvictionRunsMillis" value="30000" /> <property name="minEvictableIdleTimeMillis" value="30000" /> <!-- 應對網路不穩定的策略 --> <!-- <property name="testOnBorrow" value="true" /> <property name="validationInterval" value="30000" /> <property name="validationQuery" value="select 1 from dual" /> --> <property name="testOnReturn" value="true"></property> <property name="testWhileIdle" value="true"></property> <property name="testOnBorrow" value="true" /> <property name="validationInterval" value="30000" /> <property name="validationQuery" value="select 1 from dual" /> <!-- 應對連線洩漏的策略 --> <property name="removeAbandoned" value="true" /> <property name="removeAbandonedTimeout" value="60" /> </bean> </beans>
改為c3p0後問題修復
applicationContext.xml
<!-- production環境 --> <beans profile="production"> <context:property-placeholder ignore-unresolvable="true" location="classpath*:/application.properties"/> <!-- 資料來源配置, 使用Tomcat JDBC連線池 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <!-- Connection Info --> <property name="driverClass" value="${jdbc.driver}" /> <property name="jdbcUrl" value="${jdbc.url}" /> <property name="user" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <!-- 連線數控制與連線歸還策略 --> <property name="maxPoolSize" value="${c3p0.maxPoolSize}" /> <property name="minPoolSize" value="${c3p0.minPoolSize}" /> <property name="initialPoolSize" value="${c3p0.initialPoolSize}" /> <property name="maxIdleTime" value="${c3p0.maxIdleTime}" /> <property name="acquireIncrement" value="${c3p0.acquireIncrement}" /> <property name="idleConnectionTestPeriod" value="${c3p0.idleConnectionTestPeriod}" /> </bean> </beans>
#application.properties
#mysql database setting
jdbc.driver=com.mysql.jdbc.Driver
#production
jdbc.url=jdbc:mysql://127.0.0.1:3306/db?autoReconnect=true&failOverReadOnly=false&initialTimeout=3&useUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=root
#connection pool settings
jdbc.pool.minIdle=1
jdbc.pool.maxIdle=10
jdbc.pool.maxActive=30
jdbc.pool.maxWait=12000
#c3p0 settings
c3p0.maxPoolSize=20
c3p0.minPoolSize=5
c3p0.initialPoolSize=10
c3p0.maxIdleTime=120
c3p0.acquireIncrement=2
c3p0.idleConnectionTestPeriod=60