使用c3p0与DBCP连接池,造成的MySql 8小时问题解决方案_MySQL
本文提供了对c3p0与DBCP连接池连接MySql数据库时, 8小时内无请求自动断开连接的解决方案。首先介绍一下我在项目(c3p0连接池)中遇到的问题,后面还提供了使用DBCP连接池的解决方案。
基本问题解决
项目环境:
Java Web项目框架为Spring MVC+JPA,使用c3p0连接池,发布环境为Tomcat 7
错误描述:
项目运行一段时间(大概几个小时)之后访问时会出现第一次访问报错,再次访问正常的现象,且多次出现此问题。
报错日志:
[plain] view plaincopyprint?
- 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:428)
- at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:372)
- at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:417)
- at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:255)
- at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
- at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
- at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631)
-
at com.appcarcare.cube.service.UserService$$EnhancerByCGLIB$$a4429cba.getUserDao(
) - at com.appcarcare.cube.servlet.DataCenterServlet$SqlTimer.connectSql(DataCenterServlet.java:76)
- at com.appcarcare.cube.servlet.DataCenterServlet$SqlTimer.run(DataCenterServlet.java:70)
- at java.util.TimerThread.mainLoop(Timer.java:555)
- at java.util.TimerThread.run(Timer.java:505)
- Caused by: javax.persistence.PersistenceException: org.hibernate.TransactionException: JDBC begin transaction failed:
- at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1387)
- at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1310)
- at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:1397)
- at org.hibernate.ejb.TransactionImpl.begin(TransactionImpl.java:62)
- at org.springframework.orm.jpa.DefaultJpaDialect.beginTransaction(DefaultJpaDialect.java:71)
- at org.springframework.orm.jpa.vendor.HibernateJpaDialect.beginTransaction(HibernateJpaDialect.java:60)
- at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:378)
- ... 11 more
- Caused by: org.hibernate.TransactionException: JDBC begin transaction failed:
- at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:76)
- at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:160)
- at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1426)
- at org.hibernate.ejb.TransactionImpl.begin(TransactionImpl.java:59)
- ... 14 more
- Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
- The last packet successfully received from the server was 1,836,166 milliseconds ago. The last packet sent successfully to the server was 29,134 milliseconds ago.
- at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
- at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
- at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
- at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
- at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
- at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1117)
- at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3567)
- at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3456)
- at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3997)
- at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2468)
- at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2629)
- at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2713)
- at com.mysql.jdbc.ConnectionImpl.setAutoCommit(ConnectionImpl.java:5060)
- at com.mchange.v2.c3p0.impl.NewProxyConnection.setAutoCommit(NewProxyConnection.java:881)
- at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:72)
- ... 17 more
- Caused by: java.net.SocketException: Software caused connection abort: recv failed
- at java.net.SocketInputStream.socketRead0(Native Method)
- at java.net.SocketInputStream.read(SocketInputStream.java:150)
- at java.net.SocketInputStream.read(SocketInputStream.java:121)
- at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:114)
- at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:161)
- at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:189)
- at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:3014)
- at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3467)
- ... 25 more
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
|
原因分析:
MySQL服务器默认的“wait_timeout”是28800秒即8小时,意味着如果一个连接的空闲时间超过8个小时,MySQL将自动断开该连接,而连接池却认为该连接还是有效的(因为并未校验连接的有效性),当应用申请使用该连接时,就会导致上面的报错。
解决方案(解决这个问题的办法有三种,推荐第二种):
1. 增加 MySQL 的 wait_timeout 属性的值
修改mysql安装目录下的配置文件 my.ini文件(如果没有此文件,复制“my-default.ini”文件,生成“复件 my-default.ini”文件。将“复件 my-default.ini”文件重命名成“my.ini” ),在文件中设置:
[plain] view plaincopyprint?
- wait_timeout=31536000
- interactive_timeout=31536000
1 2 |
|
这两个参数的默认值是8小时(60*60*8=28800)。
注意: 1.wait_timeout的最大值只允许2147483 (24天左右)
2.修改配置文件为网上大部分文章所提供的方式,也可以使用mysql命令对这两个属性进行修改
2. 减少连接池内连接的生存周期
减少连接池内连接的生存周期,使之小于上一项中所设置的wait_timeout 的值。
修改 c3p0 的配置文件,在 Spring 的配置文件中设置:
[java] view plaincopyprint?
"dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> -
"maxIdleTime" value="1800"/>
1 2 3 4 |
|
3. 定期使用连接池内的连接
定期使用连接池内的连接,使得它们不会因为闲置超时而被 MySQL 断开。
修改 c3p0 的配置文件,在 Spring 的配置文件中设置:
[java] view plaincopyprint?
-
"dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> -
"preferredTestQuery" value="SELECT 1"/> -
"idleConnectionTestPeriod" value="18000"/> -
"testConnectionOnCheckout" value="true"/>
1 2 3 4 5 |
|
知识扩展
C3P0
C3P0是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate一起发布,包括了实现jdbc3和jdbc2扩展规范说明的Connection 和Statement 池的DataSources 对象。 c3p0配置文件
[html] view plaincopyprint?
- default-config>
- property name="acquireIncrement">3property>
- property name="acquireRetryAttempts">30property>
- property name="acquireRetryDelay">1000property>
- property name="autoCommitOnClose">falseproperty>
- property name="idleConnectionTestPeriod">60property>
- property name="initialPoolSize">3property>
- property name="maxIdleTime">60property>
- property name="maxPoolSize">15property>
- property name="maxStatementsPerConnection">property>
- property name="overrideDefaultPassword">passwordproperty>
- property name="password">property>
- property name="propertyCycle">300property>
- property name="testConnectionOnCheckin">trueproperty>
- property name="user">rootproperty>
- 在Hibernate(spring管理)中的配置:
- bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
- property name="driverClass">value>oracle.jdbc.driver.OracleDrivervalue>property>
- property name="jdbcUrl">value>jdbc:oracle:thin:@localhost:1521:Testvalue>property>
- property name="user">value>Kayvalue>property>
- property name="password">value>rootvalue>property>
- property name="minPoolSize" value="10" />
- property name="maxPoolSize" value="100" />
- property name="maxIdleTime" value="1800" />
- property name="acquireIncrement" value="3" />
- property name="maxStatements" value="1000" />
- property name="initialPoolSize" value="10" />
- property name="idleConnectionTestPeriod" value="60" />
- property name="acquireRetryAttempts" value="30" />
- property name="breakAfterAcquireFailure" value="true" />
- property name="testConnectionOnCheckout" value="false" />
- bean>
- ###########################
- ### C3P0 Connection Pool###
- ###########################
- #hibernate.c3p0.max_size 2
- #hibernate.c3p0.min_size 2
- #hibernate.c3p0.timeout 5000
- #hibernate.c3p0.max_statements 100
- #hibernate.c3p0.idle_test_period 3000
- #hibernate.c3p0.acquire_increment 2
- #hibernate.c3p0.validate false
- 在hibernate.cfg.xml文件里面加入如下的配置:
- property name="hibernate.c3p0.max_size">20property>
- property name="hibernate.c3p0.min_size">5property>
- property name="hibernate.c3p0.timeout">120property>
- property name="hibernate.c3p0.max_statements">100property>
- property name="hibernate.c3p0.idle_test_period">120property>
- property name="hibernate.c3p0.acquire_increment">2property>
- property name="hibernate.c3p0.validate">trueproperty>
<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> </default-config>

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











페르마의 마지막 정리, AI가 정복할 것인가? 그리고 무엇보다 가장 의미 있는 부분은 AI가 풀려고 하는 페르마의 마지막 정리가 바로 AI가 쓸모없다는 것을 증명한다는 점이다. 옛날에는 수학이 순수한 인간 지능의 영역에 속했지만 지금은 이 영역이 고급 알고리즘에 의해 해독되고 짓밟히고 있습니다. Image 페르마의 마지막 정리는 수세기 동안 수학자들을 당황하게 만든 "악명 높은" 퍼즐입니다. 이는 1993년에 입증되었으며 이제 수학자들은 컴퓨터를 사용하여 증명을 재현하는 큰 계획을 세웁니다. 그들은 이 버전의 증명에 논리적 오류가 있으면 컴퓨터로 확인할 수 있기를 바랍니다. 프로젝트 주소: https://github.com/riccardobrasca/flt

C++의 기계 학습 알고리즘이 직면하는 일반적인 과제에는 메모리 관리, 멀티스레딩, 성능 최적화 및 유지 관리 가능성이 포함됩니다. 솔루션에는 스마트 포인터, 최신 스레딩 라이브러리, SIMD 지침 및 타사 라이브러리 사용은 물론 코딩 스타일 지침 준수 및 자동화 도구 사용이 포함됩니다. 실제 사례에서는 Eigen 라이브러리를 사용하여 선형 회귀 알고리즘을 구현하고 메모리를 효과적으로 관리하며 고성능 행렬 연산을 사용하는 방법을 보여줍니다.

Hibernate 다형성 매핑은 상속된 클래스를 데이터베이스에 매핑할 수 있으며 다음 매핑 유형을 제공합니다. Join-subclass: 상위 클래스의 모든 열을 포함하여 하위 클래스에 대한 별도의 테이블을 생성합니다. 클래스별 테이블: 하위 클래스별 열만 포함하는 하위 클래스에 대한 별도의 테이블을 만듭니다. Union-subclass: Joined-subclass와 유사하지만 상위 클래스 테이블이 모든 하위 클래스 열을 통합합니다.

Apple의 최신 iOS18, iPadOS18 및 macOS Sequoia 시스템 릴리스에는 사진 애플리케이션에 중요한 기능이 추가되었습니다. 이 기능은 사용자가 다양한 이유로 손실되거나 손상된 사진과 비디오를 쉽게 복구할 수 있도록 설계되었습니다. 새로운 기능에는 사진 앱의 도구 섹션에 '복구됨'이라는 앨범이 도입되었습니다. 이 앨범은 사용자가 기기에 사진 라이브러리에 포함되지 않은 사진이나 비디오를 가지고 있을 때 자동으로 나타납니다. "복구된" 앨범의 출현은 데이터베이스 손상으로 인해 손실된 사진과 비디오, 사진 라이브러리에 올바르게 저장되지 않은 카메라 응용 프로그램 또는 사진 라이브러리를 관리하는 타사 응용 프로그램에 대한 솔루션을 제공합니다. 사용자는 몇 가지 간단한 단계만 거치면 됩니다.

Java 프레임워크 보안 취약성을 분석한 결과 XSS, SQL 주입 및 SSRF가 일반적인 취약성인 것으로 나타났습니다. 솔루션에는 보안 프레임워크 버전 사용, 입력 유효성 검사, 출력 인코딩, SQL 주입 방지, CSRF 보호 사용, 불필요한 기능 비활성화, 보안 헤더 설정이 포함됩니다. 실제 사례에서는 프레임워크 버전을 업데이트하고 OGNL 표현식 검사 도구를 사용하면 ApacheStruts2OGNL 주입 취약점을 해결할 수 있습니다.

HTML은 데이터베이스를 직접 읽을 수 없지만 JavaScript 및 AJAX를 통해 읽을 수 있습니다. 단계에는 데이터베이스 연결 설정, 쿼리 보내기, 응답 처리 및 페이지 업데이트가 포함됩니다. 이 기사에서는 JavaScript, AJAX 및 PHP를 사용하여 MySQL 데이터베이스에서 데이터를 읽는 실제 예제를 제공하고 쿼리 결과를 HTML 페이지에 동적으로 표시하는 방법을 보여줍니다. 이 예제에서는 XMLHttpRequest를 사용하여 데이터베이스 연결을 설정하고 쿼리를 보내고 응답을 처리함으로써 페이지 요소에 데이터를 채우고 데이터베이스를 읽는 HTML 기능을 실현합니다.

MySQLi를 사용하여 PHP에서 데이터베이스 연결을 설정하는 방법: MySQLi 확장 포함(require_once) 연결 함수 생성(functionconnect_to_db) 연결 함수 호출($conn=connect_to_db()) 쿼리 실행($result=$conn->query()) 닫기 연결( $conn->close())

PHP에서 데이터베이스 연결 오류를 처리하려면 다음 단계를 사용할 수 있습니다. mysqli_connect_errno()를 사용하여 오류 코드를 얻습니다. 오류 메시지를 얻으려면 mysqli_connect_error()를 사용하십시오. 이러한 오류 메시지를 캡처하고 기록하면 데이터베이스 연결 문제를 쉽게 식별하고 해결할 수 있어 애플리케이션이 원활하게 실행될 수 있습니다.
