以下是我正在使用的方案:我有一个ResultSet对象在我的SQL数据库中使用某个表。我工作的项目非常大,我已经跟踪了SQL Statement,它们应该被关闭。
但是当我尝试在有问题的特定表上执行Statement时,我收到以下错误:
SQLException caught in Error Executing SQL statement :Operation 'ALTER TABLE' cannot be performed on object 'CONNECTIONS' because there is an open ResultSet dependent on that object.
在查询要检查的表之前,有没有办法确定 如果ResultSet / Statement对象正在使用相关表格,在本例中为表格" CONNECTIONS",并进一步获得ResultSet / Statement对象使用java.sql中的可用对象并关闭它以便我可以执行我的语句?
答案 0 :(得分:0)
您可以监视每个执行的Statement,在客户端代码和实际驱动程序之间插入您自己的JDBC驱动程序。有些工作要做,但概念上很简单:
您必须通过实现java.sql.Driver
,java.sql.Connection
和java.sql.Statement
来实现您自己的JDBC驱动程序作为实际驱动程序的委托(在这种情况下无需实现ResultSet) )。嘿,不要颤抖:你不必逐个编写所有的JDBC方法;实际上,为每个接口实例化一个动态代理就足够了。
动态代理必须简单地委托给目标对象。并且Statement.executeQuery()
和Connection.prepareStatement()
和Connection.prepareCall()
方法有一个特殊的行为:每当调用这些方法中的任何一个时,你应该得到第一个参数(它是一个包含SQL语句的String)并解析它寻找目标表名称(在你的例子中#34;连接")。根据所需的准确性,您应该进行完整,严格的SQL解析,或者您可以通过String.indexOf(...)
进行简单的子字符串搜索。
当解析为正时,由您决定:您可以向控制台发出完整的当前堆栈跟踪(以便您可以在以后处理它以修复客户端类)或存储源Statement对象到可访问的对象库(可能是单例映射),以便您可以从代码中的另一个点关闭它...
最后一个细节是如何用自己的"间谍"替换实际的驱动程序。驱动程序。这很简单:只需让您的驱动程序识别特殊类型的JDBC URL(例如jdbc:my-spy-driver:thin:@localhost:port:etc
),并使客户端代码使用该URL。
请注意,使用此类驱动程序会影响性能。