Java 是否有任何工具或技术来识别打开的结果集

Java 是否有任何工具或技术来识别打开的结果集,java,sql,sqlite,jdbc,aspectj,Java,Sql,Sqlite,Jdbc,Aspectj,在用于持久化数据的java应用程序的上下文中,我使用的是JDBC驱动程序。因此,我使用包来访问我的数据库 我面临一些奇怪的问题(在同一数据库上有多个连接对象的环境中),我很确定我的问题来自非封闭的ResultSet 有没有什么工具或技术可以让我在源代码中找到这些非封闭对象 编辑可能正在使用AspectJ?直接指向我的。还允许您监视JDBC连接和游标 我个人会检查代码,确保所有语句、准备语句和结果集在不需要时关闭。即使使用连接池,也只会将JDBC连接返回到池中,并关闭语句和结果集 此示例显示了我如

在用于持久化数据的java应用程序的上下文中,我使用的是JDBC驱动程序。因此,我使用包来访问我的数据库

我面临一些奇怪的问题(在同一数据库上有多个连接对象的环境中),我很确定我的问题来自非封闭的ResultSet

有没有什么工具或技术可以让我在源代码中找到这些非封闭对象

编辑可能正在使用AspectJ

直接指向我的。还允许您监视JDBC连接和游标

我个人会检查代码,确保所有语句准备语句结果集在不需要时关闭。即使使用连接池,也只会将JDBC连接返回到池中,并关闭语句和结果集

此示例显示了我如何在最终关闭中实现关闭结果集和PreparedStatement(用于保证):


这是我2美分的价值…希望它能帮助你。

一个实用的建议是添加一些调试代码,并将结果集的创建和关闭“记录”到csv文件中。稍后,您可以检查此文件并检查每个“创建”是否有“关闭”条目

因此,假设您有一个带有静态方法的实用程序类,该类允许将字符串写入文件,您可以这样做:

 ResultSet rs = stmt.executeQuery(query);
 Util.writeln(rs.hashcode() + ";create"); // add this line whenever a 
                                         // new ResultSet is created

使用Excel或任何其他电子表格程序打开csv文件,对表格进行排序,并查看结果集是否未关闭。如果是这种情况,请添加更多调试信息以清楚地标识开放集


顺便说一句,包装接口(比如JAMon)非常简单,如果你有eclipse或其他东西,它的编码只需不到15分钟。您需要包装Connection、Statement(和PreparedStatement?)和ResultSet,可以检测ResultSet包装器以跟踪和监视结果集的创建和关闭:

public MonitoredConnection implements Connection {
  Connection wrappedConnection = null;

  public MonitoredConnection(Connection wrappedConnection) {
    this.wrappedConnection = wrappedConnection;
  }

  // ... implement interface methods and delegate to the wrappedConnection

  @Override
  public Statement createStatement() {
    // we need MonitoredStatements because later we want MonitoredResultSets
    return new MonitoredStatement(wrappedConnection.createStatemet());
  }

  // ...
}
MonitoredStatement和MonitoredResultSet的情况相同(MonitoredStatement将返回包装的结果集):

最后,您应该只需要修改代码中的一行:

Connection con = DriverManager.getConnection(ur);


使用您选择的AOP插入代码应该相对简单。几年前,我使用AspectWerkz进行web应用程序的加载时编织,并收集与性能相关的统计数据。另外,如果您使用的是IOC框架,例如Spring,那么打包数据源和跟踪对getConnection()的调用就非常容易了。

这似乎是一个有用的方面

如何包装在方面中返回结果集的方法。比如:

execution(public java.sql.ResultSet+ java.sql.Statement+.*(..))
另一个方面可以监视ResultSet上的close方法。也许:

execution(public * java.sql.ResultSet.close())
第一个方面是,在返回每个ResultSet时,创建一个新的异常对象,并使用ResultSet的哈希作为键将其存储在某个静态映射中。第二个方面,在关闭结果集时,将使用与键相同的哈希代码从映射中删除异常。在任何时候,对于每个打开的ResultSet,映射都应该有一个异常实例。从异常中可以获得堆栈跟踪,以查看结果集的打开位置


您也许可以存储一个较大的对象,其中包括一个异常和一些其他上下文信息;创建结果集的时间等。

我的问题是,我有很多对stmt.executeQuery的调用,因此我正在寻找一种方法来避免手动检查代码,并确保所有语句、PreparedStatement和结果集都已关闭。谢谢你的JAMon造型。“检查代码并确保所有语句、PreparedStatement和ResultSet都已关闭”的手动解决方案令人厌烦;-)我想避免它。使用工具管理打开的游标也不是那么容易。你需要做的一件事就是看看这些游标是在使用中还是停滞了,这很难说。
public MonitoredResultSet implements ResultSet {
  private ResultSet wrappedResultSet;

  @Override 
  public void close() {
     wrappedResultSet.close();
     ResultSetMonitor.close(wrappedResultSet); // some static utility class/method
  }

  // ...
}
Connection con = DriverManager.getConnection(ur);
Connection con = new MonitoredConnection(DriverManager.getConnection(ur));
execution(public java.sql.ResultSet+ java.sql.Statement+.*(..))
execution(public * java.sql.ResultSet.close())