【问题标题】:PreparedStatement, DDL change doesn't change ResultSet on Db2PreparedStatement,DDL 更改不会更改 Db2 上的 ResultSet
【发布时间】:2022-10-02 00:23:26
【问题描述】:

我有一个基于 Java 的应用程序,我在其中发出使用 PreparedStatement 的查询。这些准备好的语句缓存在我的连接实现层中,然后根据驱逐例程被丢弃。

我偶然发现的问题是,如果我使用以下查询生成PreparedStatement

SELECT FUNCTION(..) as A, T.* FROM table t WHERE ...

如果我稍后发出ALTER TABLE table ... 语句并且上述准备好的被重用,如果我在ALTER 中添加一个新列,则该列在准备好的语句的结果集中不可见。如果语句过期并因此被关闭,或者如果在ALTER 之后手动关闭语句并且我使用了新的准备好的语句,我会得到添加的新列。

我有几个问题:

  1. 谁能解释发生了什么,因为我没有观察到其他供应商的情况?
  2. 这种缓存是否使用PreparedStatement 控制在驱动程序或数据库级别?
  3. 如果它在驱动程序级别,是否可以禁用此行为?

    更新
    我们使用以下驱动程序显式连接到 Linux 上的 IBM Db2 11.5 实例:

            <dependency>
                <groupId>com.ibm.db2</groupId>
                <artifactId>jcc</artifactId>
                <version>11.5.0.0</version>
            </dependency>
    

    标签: java jdbc db2


    【解决方案1】:

    如果您使用的是 IBM 提供的 jdbc 驱动程序,那么以下 IBM 语句可以回答您的问题,这与 IBM 类型 4 jdbc 驱动程序有关。如果您涉及其他层,则可能适用不同的答案。

    IBM Data Server Driver for JDBC and SQLJ 不检查是否 内部语句目标对象的定义 语句缓存已更改。如果执行 SQL 数据定义 应用程序中的语言语句,您需要禁用内部 该应用程序的语句缓存。

    该声明来自documentation。换句话说,当对已经存在缓存preparedStatement 的表使用ALTER TABLE.... 时,缓存preparedStatement 不会自动失效。

    您可以禁用preparedStatement 缓存(通过调整maxStatements 属性)或在应用程序未运行时执行DDL 调整,或使用一些缓存清除技术。

    从您的问题中不清楚是否已进行基准测试以证明语句缓存对工作负载有益。

    【讨论】:

    • 我检查了数据库元数据并且未启用语句池,并且在将maxStatementsstatementCacheSize 作为0 传递后,准备好的语句继续使用ALTER 之前的表结构。我已经用驱动程序详细信息更新了原始帖子,以防万一。
    • 您应该使用最新版本的 4 驱动程序,特别是 11.5.7.0 (驱动程序是 db2jcc4.jar 构建是 4.31.10 )。这将减少随后修复的某些驱动程序错误的机会。但是,IBM 链接中的信息应该是正确的。如果您有疑问,请向 IBM 开具支持票。
    猜你喜欢
    • 2020-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-16
    • 1970-01-01
    • 1970-01-01
    • 2017-10-22
    • 1970-01-01
    相关资源
    最近更新 更多