当我的应用程序失去连接时,我应该如何恢复它?
我有一个应用程序,我正在连接到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
- Jsf动态添加/删除c:forEach循环中的组件
- 为什么没有为Jersey控制器检测到我的Aspect(使用自定义注释)?
- GSON – 特定情况下的自定义序列化程序
- 如何在swift中将字符串(在Java中使用加密MessageDigest)编码为Base64字符串?
- 在Grails战中包含Liberation .ttf字体?
- 如何将图像分割成多个较小的图像
- 我最大化JInternalFrame时在JInternalFrame上编写JMenubar示例
- Apache Kafka和Avro:org.apache.avro.generic.GenericData $ Record无法强制转换为com.harmeetsingh13.java.Customer
- 对内部类的局部变量访问需要声明为final