【问题标题】:C3P0 Throws Exception in case of @transactionalC3P0 在@transactional 的情况下抛出异常
【发布时间】:2015-05-01 18:15:59
【问题描述】:

您好,我正在使用Hibernate core 4.3.1 FINALhibernate-c3p0 4.3.1 FINAL。使用 JPA 持久化配置如下。

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">

<persistence-unit name="somename">
    <description>

    </description>

    <properties>
        <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
        <property name="javax.persistence.jdbc.url"
            value="jdbc:mysql://localhost:3306/somename?autoReconnect=true" />
        <property name="javax.persistence.jdbc.user" value="root" />
        <property name="javax.persistence.jdbc.password" value="admin" />

        <property name="hibernate.show_sql" value="true" />
        <property name="hibernate.hbm2ddl.auto" value="none" />
        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
        <property name="hibernate.connection.provider_class" value="org.hibernate.c3p0.internal.C3P0ConnectionProvider" />

        <property name="hibernate.c3p0.max_size" value="100" />
        <property name="hibernate.c3p0.min_size" value="1" />
        <property name="hibernate.c3p0.acquire_increment" value="1" />
        <property name="hibernate.c3p0.idle_test_period" value="50" />
        <property name="hibernate.c3p0.max_statements" value="0" />
        <property name="hibernate.c3p0.timeout" value="100" />
    </properties>

</persistence-unit>

我正在像这样使用 Spring 的 JpaTransactionManager

在我使用过的服务类中。

@Transactional
public void deleteSomething (){...}

因此,每当执行此方法或任何具有事务的方法时,我都会收到以下异常:

2015-03-01 02:34:16 [DEBUG] - delete from badoc where baId=? and docId=?
Hibernate: delete from badoc where baId=? and docId=?
2015-03-01 02:34:16 [DEBUG] - com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager@4b969e3c.acquireResource() returning. 
2015-03-01 02:34:16 [DEBUG] - trace com.mchange.v2.resourcepool.BasicResourcePool@40873594 [managed: 2, unused: 1, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@6f5a9e8e)
2015-03-01 02:34:16 [DEBUG] - decremented pending_acquires: 0
2015-03-01 02:34:16 [DEBUG] - Acquisition series terminated successfully. Decremented pending_acquires [0],  attempts_remaining: 30
2015-03-01 02:34:16 [DEBUG] - Converting Throwable to SQLException...
java.lang.NullPointerException
    at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.maybeDirtyTransaction(NewProxyPreparedStatement.java:2520)
    at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.getMaxRows(NewProxyPreparedStatement.java:1403)
    at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.close(JdbcCoordinatorImpl.java:530)
    at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.release(JdbcCoordinatorImpl.java:407)
    at org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl.releaseStatements(AbstractBatchImpl.java:173)
    at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:76)
    at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3400)
    at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3624)
    at org.hibernate.action.internal.EntityDeleteAction.execute(EntityDeleteAction.java:113)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:453)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:345)
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:350)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56)
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1218)
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:421)
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177)
    at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:77)
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:515)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:757)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:726)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:478)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:272)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644)
    at com.pwc.atlas.service.DocumentService$$EnhancerBySpringCGLIB$$b0e32825.manageBADocument(<generated>)
    at com.pwc.atlas.rest.SolrController.manageBaDocuments(SolrController.java:463)
    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.invoke(InvocableHandlerMethod.java:215)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:690)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:945)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:876)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
    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:744)
2015-03-01 02:34:16 [DEBUG] - Exception clearing maxRows/queryTimeout [You can't operate on a closed Statement!!!]
2015-03-01 02:34:16 [DEBUG] - committed JDBC Connection
2015-03-01 02:34:16 [DEBUG] - Closing JPA EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@1295e6d1] after transaction
2015-03-01 02:34:16 [DEBUG] - Closing JPA EntityManager
2015-03-01 02:34:16 [DEBUG] - HHH000420: Closing un-released batch
2015-03-01 02:34:16 [DEBUG] - Releasing JDBC connection

事务完成,但出现此异常。

我对将 JPA 与休眠和连接池结合使用相当陌生。如果我在配置中遗漏了什么,您能帮忙吗?

【问题讨论】:

    标签: hibernate jpa c3p0 spring-transactions transactional


    【解决方案1】:

    请注意,您记录的异常仅显示在调试级别。 c3p0 在 DEBUG 级别详细记录事情。

    在这种情况下,当它被 SQLException 包装时,您记录了一个 rootCause 异常,然后 Hibernate 会处理它。显示的 rootCause 表明该语句已被 close()ed。包装异常的处理记录了一条信息更丰富的消息:

    Exception clearing maxRows/queryTimeout [You can't operate on a closed Statement!!!]
    

    Hibernate 正在尝试对 Statement 进行某种清理,并发现该 Statement 已经 close()ed。如果你在“Exception clearing maxRows/queryTimeout”上谷歌,你会发现很多关于这个问题的信息。可能的原因包括应用程序持有过时的连接和连接在服务器上超时(请参阅讨论here。这与 HikariCP 相悖。您也会发现类似的reports against DBCP。)

    请确保您的应用程序中没有任何东西可以保留已关闭的连接或会话。

    您可以使用a more reliable Connection testing scheme。特别是,我首先将hibernate.c3p0.preferredTestQuery 设置为SELECT 1 并将hibernate.c3p0.testConnectionOnCheckout 设置为true(并将hibernate.c3p0.idle_test_period 设置为0,暂时在空闲时消除测试)。

    您还可以考虑升级到 c3p0-0.9.5,它提供了许多修复和改进。 (您必须覆盖 hibernate-c3p0 4.3.1 中的默认传递依赖项。)但这可能无法解决此问题。

    【讨论】:

    • 哦,不相关,但请不要使用 1 的 acquireIncrement。为什么不坚持 c3p0 的默认值 3,甚至更高?如果您有能力将池增加到 100 个连接,那么您可以承受它一次增长 3 个,并且在池增长期间客户感知的性能将会提高。
    • 谢谢@Steve。我升级到 hibernate-c3p0 4.3.7 FINAL 版本。哪个有效。我现在没有看到那个例外。并感谢将 aquireIncrement 增加到 3 的建议。我会这样做。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多