【发布时间】:2010-12-06 11:40:31
【问题描述】:
我正在使用 JDBC 连接到数据库服务器。 连接是通过无线网络进行的,有时可能很狡猾。 在连接丢失的那一刻,我需要关闭并重新启动应用程序。
有没有人有一些代码示例,我可以在其中编写某种包装器来自动重新连接并重新运行最后一个查询?这样可以省去很多麻烦。
我只是不确定应该/可以如何实施。 也许已经有可用的东西了?
【问题讨论】:
标签: java jdbc firebird jaybird
我正在使用 JDBC 连接到数据库服务器。 连接是通过无线网络进行的,有时可能很狡猾。 在连接丢失的那一刻,我需要关闭并重新启动应用程序。
有没有人有一些代码示例,我可以在其中编写某种包装器来自动重新连接并重新运行最后一个查询?这样可以省去很多麻烦。
我只是不确定应该/可以如何实施。 也许已经有可用的东西了?
【问题讨论】:
标签: java jdbc firebird jaybird
查看 Oracle 的通用连接池 (UCP) 库。它们完全符合 JDBC 4.0 并实现 isValid() 调用以检查连接是否处于活动状态。执行此检查很容易,如果错误重新连接,则运行您的查询。
虽然我知道您没有询问连接池,但您可能还是应该使用连接池,所以这将对您有双重帮助。
【讨论】:
oracle.ucp.jdbc.ValidConnection,但是,TBH,我不认为使用供应商特定的类是一个好主意,也不推荐它。
让连接池为您处理这个问题,其中许多可以验证连接。 DBCP 也是如此,它有一个 testOnBorrow 参数,在使用之前强制对每个连接进行完整性检查。该参数的默认值为true,只需将validationQuery设置为非空字符串即可生效。所以设置validationQuery 就可以了!查看documentation。
【讨论】:
即使您使用应用程序服务器提供的 JDBC 连接池或 apache 公共池,编写重试逻辑也是值得的。根据您的应用程序服务器的配置,应用程序服务器将清除所有池连接并重新创建一组新连接。这是一个示例:
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
//
// How many times do you want to retry the transaction
// (or at least _getting_ a connection)?
//
int retryCount = 5;
boolean transactionCompleted = false;
do {
try {
conn = getConnection(); // assume getting this from a
// javax.sql.DataSource, or the
// java.sql.DriverManager
retryCount = 0;
stmt = conn.createStatement();
String query = "Some sample SQL";
rs = stmt.executeQuery(query);
while (rs.next()) {
}
rs.close();
rs = null;
stmt.close();
stmt = null;
conn.close();
conn = null;
transactionCompleted = true;
} catch (SQLException sqlEx) {
//
// The two SQL states that are 'retry-able'
// for a communications error.
//
// Only retry if the error was due to a stale connection,
// communications problem
//
String sqlState = sqlEx.getSQLState();
if ("Substitute with Your DB documented sqlstate number for stale connection".equals(sqlState) ) {
retryCount--;
} else {
retryCount = 0;
}
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException sqlEx) {
// log this
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqlEx) {
// log this
}
}
if (conn != null) {
try {
//
// If we got here, and conn is not null, the
// transaction should be rolled back, as not
// all work has been done
try {
conn.rollback();
} finally {
conn.close();
}
} catch (SQLException sqlEx) {
//
// If we got an exception here, something
// pretty serious is going on, so we better
// pass it up the stack, rather than just
// logging it. . .
throw sqlEx;
}
}
}
} while (!transactionCompleted && (retryCount > 0));
【讨论】: