1

我们在 Java 中的准备好的语句有问题。异常似乎很明显:

Root Exception stack trace: com.microsoft.sqlserver.jdbc.SQLServerException: The statement must be executed before any results can be obtained. at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:170) at com.microsoft.sqlserver.jdbc.SQLServerStatement.getGeneratedKeys(SQLServerStatement.java:1973) at org.apache.commons.dbcp.DelegatingStatement.getGeneratedKeys(DelegatingStatement.java:315)

它基本上表明我们正在尝试在执行之前获取查询结果。听起来很有道理。现在,导致此异常的代码如下:

    ...

    preparedStatement.executeUpdate();

    ResultSet resultSet = preparedStatement.getGeneratedKeys();
    if(resultSet.next()) {
        retval = resultSet.getLong(1);
    }

    ...

如您所见,我们在执行语句后获取查询结果。

在这种情况下,我们尝试从刚刚成功执行ResultSet的查询中获取生成的密钥。INSERT

问题

我们在三个不同的服务器上运行此代码(负载平衡,在 docker 容器中)。奇怪的是,这个异常发生在第三个 docker 服务器上。其他两个 docker 服务器从来没有遇到过这个异常。

额外:失败的查询每天大约执行 13000 次。(4500 由服务器 3 处理)大多数情况下,查询在服务器 3 上也能正常工作。有时,假设每天 20 次,查询失败。始终相同的查询,始终相同的服务器。从来没有其他服务器之一。

我们尝试过的

  • 我们检查了软件版本。但这都是一样的,因为所有服务器都使用相同的 docker 映像运行。
  • 我们更新到最新的 Java 微软 SQL 驱动程序
  • 我们检查了是否所有的PreparedStatements都是使用PreparedStatement.RETURN_GENERATED_KEYS参数构造的。

看起来这是一些与服务器配置相关的问题,因为 docker 图像都是一样的。但我们找不到原因。有没有人建议问题可能是什么?或者有没有人也遇到过这个问题?

4

1 回答 1

0

据我所知,SQL Server 不支持批量执行的 getGeneratedKeys() 。

这是尚未满足的功能请求:https ://github.com/Microsoft/mssql-jdbc/issues/245

我的建议是,如果由于某种原因在您的第三台服务器上批量插入连续执行,这可能会导致您提到的异常(如果在其他两个上只插入了一项)

您可以尝试记录 sql 语句来检查这一点

于 2017-11-17T22:16:35.330 回答