我在我的应用程序中配置了Hibernate DAO
。一旦客户端ping该服务,我的服务器将使用此DAO
连接到数据库并检索一些数据。
这可以在几个小时(或者可能是一天)中正常工作,然后出现问题。我有这样的例外:
引起:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: 从服务器成功收到的最后一个数据包是48,761,817 几毫秒之前。成功发送到服务器的最后一个数据包是 48,761,899毫秒之前。比配置的服务器长 'wait_timeout'的值。你应该考虑到期和/或 在您的应用程序中使用前测试连接有效性,增加 服务器配置的客户端超时值,或使用 连接器/ J连接属性'autoReconnect = true'以避免这种情况 问题
重新部署服务后,一切恢复正常。我的代码是这样的:
公共类DeploymentInfoDAO {
private static SessionFactory factory = null;
private DeploymentInfo deploymentInfo = null;
private CheckLockStatusService checkLockStatusService = new CheckLockStatusService();
/**
* Constructor
*/
public DeploymentInfoDAO() {
}
/**
* Constructor
*
* @param deploymentInfo
*/
public DeploymentInfoDAO(DeploymentInfo deploymentInfo) {
this.deploymentInfo = deploymentInfo;
// this.checkLockStatusService = new CheckLockStatusService();
}
/**
* SELECT * FROM servicedashboard and converts the results into a list of
* ServiceRow
*
* @return
*/
public List<ServiceRow> getServiceRows() {
List<ServiceRow> serviceRows = new ArrayList<ServiceRow>();
if (factory == null){
try {
factory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError(ex);
}
}
// mysql select test
Session session = factory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
List<DeploymentInfo> deploymentInfos = session
.createQuery(
"FROM com.test.hibernate.pojo.DeploymentInfo")
.list();
for (Iterator<DeploymentInfo> iterator = deploymentInfos.iterator(); iterator
.hasNext();) {
DeploymentInfo deploymentInfo = iterator.next();
ServiceRow serviceRow = this
.convertToServiceRow(deploymentInfo);
serviceRows.add(serviceRow);
}
tx.commit();
} catch (HibernateException e) {
if (tx != null)
tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
return serviceRows;
}
}
基本上,每次客户来电都会创建一个DeploymentInfoDAO
,一旦创建,它将继续使用相同的static
SessionFactory
,直到它不是null
。
似乎在几个小时后,此SessionFactory
变为无效但仍然不为空。
修改代码的最佳做法是什么?而且,在例外中,它建议using the Connector/J connection property 'autoReconnect=true'
避免这个问题,如何做到这一点?
答案 0 :(得分:2)
实际上,您的服务器在闲置8小时后终止与MySQL的连接(默认为8小时)
您可以在jdbc url中使用autoReconnect=true
jdbc:mysql://<host>:<port>/<db>?autoReconnect=true
答案 1 :(得分:0)
尝试增加服务器中的等待超时或在JDBC URL中启用自动重新连接。
答案 2 :(得分:0)
多年前我遇到了同样的问题。这是因为MySQL在一段时间不活动后关闭连接,这不是你的应用程序的问题。
一种解决方案是创建一个虚拟查询(SELECT 1
)并每小时(或您估计的时间)执行它。这可以避免MySQL关闭连接。
另一个是增加MySQL的时间限制(这个解决方案我不喜欢它,很多时候由于某些原因无法修改数据库配置)。
更多信息:
Terminating idle mysql connections
http://dev.mysql.com/doc/refman/5.0/en/server-system-variables.html#sysvar_wait_timeout
我希望这对你有所帮助。