一段时间后失去与 MySQL 的连接,并且没有重新连接

Posted

技术标签:

【中文标题】一段时间后失去与 MySQL 的连接,并且没有重新连接【英文标题】:Losing connection to MySQL after a while, and not reconnecting 【发布时间】:2011-06-30 21:55:48 【问题描述】:

我正在开发一个使用 JPA+Hibernate 访问 mysql 数据库的独立服务器。

当我启动服务器时,一切正常。但是,过了一段时间(通常是第二天早上,如果我在下午启动它)它将停止工作,因为显然与 MySQL 的连接已关闭(我在日志中看到很多 SocketExceptions)。这可能是由于闲置造成的,服务器正在开发中,没有人在晚上使用它。

我认为 Hibernate、JDBC 或我的应用程序下方的其他一些层会管理连接并在必要时重新打开它,但显然不是。有没有我遗漏的配置参数?

persistence.xml

http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" 版本="2.0">

<persistence-unit name="manager">

<class>example.data.entities.User</class>
<class>example.data.entities.Player</class>

<properties>
    <property name="hibernate.dialect" value="example.data.HibernateDialect" />
    <property name="hibernate.max_fetch_depth" value="3" />
    <property name="hibernate.hbm2ddl.auto" value="update" />

    <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />

</properties>

</persistence-unit>

EntityManagerFactory创作

    log.info("Connecting to database @ " + dbUrl + " using " + dbUser + "/" + dbPass);

    emf = Persistence.createEntityManagerFactory("manager", Maps.create(
            "javax.persistence.jdbc.user", dbUser,
            "javax.persistence.jdbc.password", dbPass,
            "javax.persistence.jdbc.url", dbUrl
    ));

查询

            try
            

                TypedQuery<User> q = em.createQuery("SELECT u FROM User u WHERE u.email = :mail", User.class);
                q.setParameter("mail", email);
                try 
                    u = q.getSingleResult();
                    log.info("Authenticating: " + u);
                 catch (NoResultException e) 
                    return false;
                

             finally 
                em.close();
            

【问题讨论】:

【参考方案1】:

正如你所建议的,这是因为mysql在每次wait_timeout通过后关闭空闲连接;您可以通过一些选项来解决您的问题:

使用连接池管理器,如c3p0 或apache DBCP。这将负责根据请求重新验证连接,最终您可以指定运行哪个查询来测试连接是否处于活动状态。 在 mysql 中设置足够大的 wait_timeout 以供您使用(默认为 8 小时)。 设置刷新连接、“ping”mysql 服务器的计划任务(例如使用quartz)。

【讨论】:

我现在正在使用 c3p0。我不明白的是在一个池中拥有多个连接的好处,但它是包的一部分,所以现在我有了它:p。对我有什么好处? @Bart van Heukelom:这是使用数据库连接的不同合同,您可以在打开连接时假设连接已准备就绪,这减少了关闭连接的开销(使用池,只不过是向池管理器发出您停止使用连接的信号)。使用池管理器时,请记住在不需要时立即关闭每个 jdbc 对象。【参考方案2】:

mysql驱动支持自动重连 jdbc url 看起来像 jdbc:mysql://localhost/bms_company?autoReconnect=true

如果你怀疑 mysql 正在断开连接 尝试在 MySQL 的 my.ini 文件末尾添加以下条目。这个文件 位于 MySQL 安装的根文件夹中。

#mysqld服务器等待连接数据包的秒数 在回应“握手错误”之前 连接超时=0

#服务器等待交互活动的秒数 关闭之前的连接。 交互超时=2000000

#服务器在连接之前等待活动的秒数 关闭它 wait_timeout=2000000

--Kiran.Kumar

【讨论】:

第一个听起来不错,但对我不起作用。将超时设置为如此大的值会引发其他问题:如果应用程序崩溃(在我的情况下为 tomcat)连接将保持活动几天,这可能会引发 mysql 的“连接过多”错误。

以上是关于一段时间后失去与 MySQL 的连接,并且没有重新连接的主要内容,如果未能解决你的问题,请参考以下文章

activerecord的一个猴子补丁,用于在失去与mysql服务器的连接后重新连接

Spring 应用程序在 8 小时后失去与 MySql 的连接。如何正确配置?

我在我的 Node.js 应用程序中使用 MongoSkin,在一段时间不活动后,它失去了与数据库的连接

查询期间失去与 MySQL 服务器的连接

超时重新连接 MySQL

NodeJS - MySQL 服务器在一段时间后无法工作