当我的应用程序失去连接时,我应该如何恢复它?

我有一个应用程序,我正在连接到MySQL数据库。 它在半夜失去连接,然后喷出null连接,并且JDBC在X秒内没有收到消息。

在我做任何需要与SQL服务器通信的事情之前,我调用了getConnection()

这是我的getConnection()方法:

 private Connection getConnection() { try { if (connection != null) { if (connection.isClosed() || !connection.isValid(10000)) { this.initializeRamsesConnection(); } } else { this.initializeRamsesConnection(); } } catch (Exception e) { debug("Connection failed: " + e); } return connection; } 

initializeRamsesConnection()方法中,我将密码等信息放入字符串中,然后以标准JDBC方式创建连接。

然后我称这个方法:

 private Connection getConnectionFromConnectionString() { Connection con = null; String driver = "com.mysql.jdbc.Driver"; try { Class.forName(driver);//jdbc sorcery //if there is no connection string if (getConnectionString() == null) { HMIDatabaseAdapter.debug("No connection string"); } //makes a string out of the values of db/host String str = getConnectionString(); //if there is no driver if (driver == null) { debug("" + ": " + "No driver"); } //Tries to make a connection from the connection string, username, and the password. con = DriverManager.getConnection(str, username, password); //if for some reason the connection is null if (con == null) { HMIDatabaseAdapter.debug("CONNECTION IS NULL, WHAT?"); } } catch (Exception ex) { HMIDatabaseAdapter.debug("getConnection() " + ex); } return con; } 

我可以在这些方法中更改哪些内容以适应丢失连接?

这不是检索连接的正确方法。 您正在检索连接并将其指定为类的实例(或更糟,静态)变量。 基本上,您将永远保持连接打开,并为所有查询重用单个连接。 如果查询由不同的线程执行,这可能最终导致灾难。 此外,当它保持打开时间过长时,DB会收回它,因为它假定它已经死亡/泄漏。

您应该在尽可能短的范围内获取并关闭连接。 即在您执行查询的同一个try块中。 像这样的东西:

 public Entity find(Long id) throws SQLException { Entity entity = null; try ( Connection connection = dataSource.getConnection(); // This should return a NEW connection! PreparedStatement statement = connection.prepareStatement(SQL_FIND); ) { statement.setLong(1, id); try (ResultSet resultSet = preparedStatement.executeQuery()) { if (resultSet.next()) { entity = new Entity( resultSet.getLong("id"), resultSet.getString("name"), resultSet.getInt("value") ); } } } return entity; } 

如果您担心连接性能并希望重用连接,那么您应该使用连接池。 你可以养一个,但我强烈反对这一点,因为你似乎对这些东西很新。 只需使用现有的连接池,如BoneCP , C3P0或DBCP 。 请注意,您不应更改JDBC惯用法,如上例所示。 您仍然需要在尽可能短的范围内获取和关闭连接。 连接池本身会担心实际重用,测试和/或关闭连接。

也可以看看:

  • 我使用JDBC连接池吗?
  • JDBC MySql连接池实践,以避免耗尽连接池

你的代码中哪里有丢失连接的错误? 这可能是最好的起点。

脱离我的头脑(我可能是错的),JDBC连接只会关闭实际的致命错误,所以在你尝试做某事之前你不会知道它们已经失败了。

我过去所做的是在失败时使连接无效并定期重试。

也许这就是你要找的: http : //dev.mysql.com/doc/refman/5.0/en/auto-reconnect.html

对于java,请参阅autoReconnect: http : //dev.mysql.com/doc/refman/5.0/en/connector-j-reference-configuration-properties.html