【问题标题】:com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closedcom.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:连接关闭后不允许操作
【发布时间】:2011-11-25 18:43:57
【问题描述】:

我构建了一个应用程序并在本地部署......它运行良好。我将它部署在远程服务器上并开始收到主题行中提到的异常。这不是因为任何防火墙问题。

我更改了我的hibernate.xml 以通过我的 IP 地址而不是 localhost 进行连接,现在我在本地部署的应用程序上得到了相同的超时。当我让应用程序运行超过一天时出现此错误。

我自己提交事务或关闭会话后没有执行任何操作。我在hibernate.cfg.xml中使用以下属性

<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://myremotehost:3306/akp</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">root</property>
        <property name="hibernate.show_sql">false</property>
        <property name="hibernate.current_session_context_class">thread</property>
        <property name="hibernate.query.factory_class">org.hibernate.hql.ast.ASTQueryTranslatorFactory</property>

原因:com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:连接关闭后不允许操作。连接被驱动程序隐式关闭。

详细说明:

 Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.Connection was implicitly closed by the driver.
      at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
      at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
      at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
      at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
      at com.mysql.jdbc.Util.handleNewInstance(Util.java:409)
      at com.mysql.jdbc.Util.getInstance(Util.java:384)
      at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1015)
      at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989)
      at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:984)
      at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:929)
      at com.mysql.jdbc.ConnectionImpl.throwConnectionClosedException(ConnectionImpl.java:1193)
      at com.mysql.jdbc.ConnectionImpl.checkClosed(ConnectionImpl.java:1180)
      at com.mysql.jdbc.ConnectionImpl.prepareStatement(ConnectionImpl.java:4137)
      at com.mysql.jdbc.ConnectionImpl.prepareStatement(ConnectionImpl.java:4103)
      at org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:505)
      at org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:423)
      at org.hibernate.jdbc.AbstractBatcher.prepareQueryStatement(AbstractBatcher.java:139)
      at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1547)
      at org.hibernate.loader.Loader.doQuery(Loader.java:673)
      at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
      at org.hibernate.loader.Loader.doList(Loader.java:2220)
      ... 36 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 34,247,052 milliseconds ago.  The last packet sent successfully to the server was 34,247,052 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.
      at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
      at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
      at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
      at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
      at com.mysql.jdbc.Util.handleNewInstance(Util.java:409)
      at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1118)
      at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3321)
      at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1940)
      at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2113)
      at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2568)
      at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2113)
      at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2275)
      at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:186)
      at org.hibernate.loader.Loader.getResultSet(Loader.java:1787)
      at org.hibernate.loader.Loader.doQuery(Loader.java:674)
      at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
      at org.hibernate.loader.Loader.doList(Loader.java:2220)
      at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2104)
      at org.hibernate.loader.Loader.list(Loader.java:2099)
      at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:94)
      at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1569)
      at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:283)
      at com.xyz.abc.DAO.GenericHibernateDAO.findByField(GenericHibernateDAO.java:119)
      at com.xyz.abc.DAO.JobDAO.getJobsByLdap(JobDAO.java:115)
      at com.xyz.abc.business.Jcr.getMyruns(Jcr.java:272)
      at com.xyz.abc.business.abcService.getMyruns(abcService.java:54)
      at sun.reflect.GeneratedMethodAccessor139.invoke(Unknown Source)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at org.apache.axis2.rpc.receivers.RPCUtil.invokeServiceClass(RPCUtil.java:194)
      at org.apache.axis2.rpc.receivers.RPCMessageReceiver.invokeBusinessLogic(RPCMessageReceiver.java:102)
      at org.apache.axis2.receivers.AbstractInOutMessageReceiver.invokeBusinessLogic(AbstractInOutMessageReceiver.java:40)
      at org.apache.axis2.receivers.AbstractMessageReceiver.receive(AbstractMessageReceiver.java:114)
      at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:173)
      at org.apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HTTPTransportUtils.java:173)
      at org.apache.axis2.transport.http.AxisServlet.doPost(AxisServlet.java:142)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
      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:208)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:203)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:108)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:379)
      at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:242)
      at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:259)
      at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:237)
      ... 4 more
Caused by: java.net.SocketException: Software caused connection abort: socket write error

有没有人知道什么可能导致这种行为?

编辑: 现在在我的 hibernate.cfg.xml 文件中使用以下内容。是否正确?

<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/xyz</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">root</property>
    <property name="hibernate.show_sql">false</property>
    <property name="hibernate.current_session_context_class">thread</property>
    <property name="hibernate.query.factory_class">org.hibernate.hql.ast.ASTQueryTranslatorFactory</property>
    <property name="hibernate.c3p0.min_size">5</property>
    <property name="hibernate.c3p0.max_size">20</property>
<!-- <property name="hibernate.c3p0.max_size">1800</property>-->
    <property name="hibernate.c3p0.max_statements">50</property>

    <property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
    <property name="c3p0.max_statements">0</property>
    <property name="c3p0.maxIdleTimeExcessConnections">3600</property>
    <property name="c3p0.idleConnectionTestPeriod">3600</property> 
    <property name="c3p0.maxIdleTime">3600</property>

【问题讨论】:

    标签: java mysql hibernate


    【解决方案1】:

    正如@swanliu 指出的那样,这是由于连接不良。
    但是在调整服务器计时和客户端超时之前,我会先尝试使用更好的连接池策略。 p>

    连接池

    Hibernate 自己承认它的连接池策略是最小的

    然而,Hibernate 自己的连接池算法相当 初级的。它旨在帮助您入门,而不是 用于生产系统,甚至用于性能 测试。您应该使用第三方池以获得最佳性能和 稳定。只需替换 hibernate.connection.pool_size 属性 具有连接池特定设置。这将关闭 Hibernate 的 内部池。例如,您可能喜欢使用 c3p0。
    如参考中所述http://docs.jboss.org/hibernate/core/3.3/reference/en/html/session-configuration.html

    我个人使用C3P0。但是还有其他选择,包括DBCP
    看看

    以下是我的应用程序中使用的 C3P0 的最小配置:

    <property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
    <property name="c3p0.acquire_increment">1</property> 
    <property name="c3p0.idle_test_period">100</property> <!-- seconds --> 
    <property name="c3p0.max_size">100</property> 
    <property name="c3p0.max_statements">0</property> 
    <property name="c3p0.min_size">10</property> 
    <property name="c3p0.timeout">1800</property> <!-- seconds --> 
    

    默认情况下,连接池永远不会过期。如果你希望 连接会随着时间的推移而过期,以保持“新鲜感”, 设置 maxIdleTime 和/或 maxConnectionAge。 maxIdleTime 定义了多少 秒一个连接应该被允许在被使用之前去未使用 从池中剔除。 maxConnectionAge 强制池剔除任何 从数据库获取的连接数多于集合 过去的秒数。
    如参考中所述: http://www.mchange.com/projects/c3p0/index.html#managing_pool_size

    编辑:
    我更新了配置文件 (Reference),因为我刚刚为我的项目复制粘贴了一个。 理想情况下,超时应该可以解决问题,如果这对您不起作用,那么我认为您可以查看一个昂贵的解决方案

    创建一个文件“c3p0.properties”,该文件必须位于类路径的根目录中(即无法为应用程序的特定部分覆盖它)。 (Reference)

    # c3p0.properties
    c3p0.testConnectionOnCheckout=true
    

    使用此配置,每个连接在使用前都经过测试。但是,它可能会影响网站的性能。

    【讨论】:

    • @rictionlesspulley:我添加了 c3po jar 并更改了我的 hibernate.cfg.xml。您能否验证它是否正确?我已将其发布在我对原始帖子的新编辑中。
    • 使用连接池后是否仍然出现异常
    • 当我让我的应用程序运行很长时间(例如 8 小时以上)时,我得到了这个异常。我现在一直运行它会看到结果并回来
    • 我刚刚更新了配置。也试试我建议的 c3p0 属性。它可能会使您的应用程序正常工作,但会带来性能问题。
    【解决方案2】:

    MySQL 隐式关闭了数据库连接,因为连接已不活动太长时间(34,247,052 毫秒 ≈ 9.5 小时)。 如果您的程序随后从导致MySQLNonTransientConnectionException: No operations allowed after connection closed 的连接池中获取错误连接。

    MySQL 建议:

    在您的应用程序中使用之前,您应该考虑过期和/或测试连接有效性,增加客户端超时的服务器配置值,或使用 Connector/J 连接属性autoReconnect=true 来避免这个问题。

    【讨论】:

    • 感谢您的回复。在我的应用程序中,我正在做一个交易,然后我生成一个 xml 文件,然后将其发送给客户端,然后我关闭交易。我这样做是我有很多懒惰的获取。
    • :我现在在我的原始帖子中发布了我的 hibernate.cfg.xml。你能帮我配置它,以便我可以摆脱这个异常吗?
    【解决方案3】:

    如果你不想使用连接池(你确定你的应用只有一个连接),你可以这样做 - 如果连接失败,你必须建立一个新的 - 调用方法 .openSession() 而不是 .getCurrentSession()

    例如:

    SessionFactory sf = null;
    // get session factory
    // ...
    //
    Session session = null;
    try {
            session = sessionFactory.getCurrentSession();
    } catch (HibernateException ex) {
            session = sessionFactory.openSession();
    }
    

    如果你使用Mysql,你可以设置autoReconnect属性:

        <property name="hibernate.connection.url">jdbc:mysql://127.0.0.1/database?autoReconnect=true</property>
    

    我希望这会有所帮助。

    【讨论】:

      【解决方案4】:
      1. 首先替换下面给出的 MySQL 依赖项

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.44</version>
        </dependency>
        
      2. 将出现显示“身份验证插件'caching_sha2_password'”的错误。运行这个命令:

        mysql -u root -p
        ALTER USER 'username'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
        

      【讨论】:

      • 此响应可能仍适用于面临相同问题且未通过接受的响应修复的其他人。它对我有用。谢谢卡兰。
      【解决方案5】:

      请确保您使用的是最新的 jdbc 连接器,符合 mysql。我遇到了这个问题,当我用最新的 jdbc 连接器替换旧的 jdbc 连接器时,问题就解决了。

      你可以从https://dev.mysql.com/downloads/connector/j/下载最新的jdbc驱动

      选择操作系统作为平台无关。它将向您显示两个选项。一个是 tar,一个是 zip。下载 zip 并将其解压缩以获取 jar 文件并将其替换为旧连接器。

      这不仅适用于 hibernate 框架,它可以用于任何需要 jdbc 连接器的平台。

      【讨论】:

        【解决方案6】:

        这是由于使用过时的 mysql-connection-java 版本,您的 MySQl 已更新但未更新您的 MySQL jdbc 驱动程序,您可以从官方网站 MySQL 连接器官方网站更新您的连接 jar。 祝你好运。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-06-06
          • 1970-01-01
          • 1970-01-01
          • 2019-07-01
          • 2020-04-17
          • 2015-02-16
          • 1970-01-01
          • 2012-12-07
          相关资源
          最近更新 更多