在语句查询之前确定Statement / ResultSet是否正在使用表?

时间:2016-09-09 22:31:39

标签: java sql

以下是我正在使用的方案:我有一个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中的可用对象并关闭它以便我可以执行我的语句?

1 个答案:

答案 0 :(得分:0)

您可以监视每个执行的Statement,在客户端代码和实际驱动程序之间插入您自己的JDBC驱动程序。有些工作要做,但概念上很简单:

  1. 您必须通过实现java.sql.Driverjava.sql.Connectionjava.sql.Statement来实现您自己的JDBC驱动程序作为实际驱动程序的委托(在这种情况下无需实现ResultSet) )。嘿,不要颤抖:你不必逐个编写所有的JDBC方法;实际上,为每个接口实例化一个动态代理就足够了。

  2. 动态代理必须简单地委托给目标对象。并且Statement.executeQuery()Connection.prepareStatement()Connection.prepareCall()方法有一个特殊的行为:每当调用这些方法中的任何一个时,你应该得到第一个参数(它是一个包含SQL语句的String)并解析它寻找目标表名称(在你的例子中#34;连接")。根据所需的准确性,您应该进行完整,严格的SQL解析,或者您可以通过String.indexOf(...)进行简单的子字符串搜索。

  3. 当解析为正时,由您决定:您可以向控制台发出完整的当前堆栈跟踪(以便您可以在以后处理它以修复客户端类)或存储源Statement对象到可访问的对象库(可能是单例映射),以便您可以从代码中的另一个点关闭它...

  4. 最后一个细节是如何用自己的"间谍"替换实际的驱动程序。驱动程序。这很简单:只需让您的驱动程序识别特殊类型的JDBC URL(例如jdbc:my-spy-driver:thin:@localhost:port:etc),并使客户端代码使用该URL。

  5. 请注意,使用此类驱动程序会影响性能。