SQLexception只发生在三台服务器中的一台上

我们在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)

它基本上表明,我们正试图获取查询结果之前,已被执行。 听起来似乎有道理。 现在,导致此exception的代码如下所示:

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

正如你所看到的,我们在执行语句之后获取查询结果。

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

问题

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

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

我们试过的

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

它看起来像是一些服务器configuration相关的问题,因为docker的图像都是一样的。 但是我们找不到原因。 有没有人有什么问题可以build议? 还是有人跑过这个问题呢?

据我所知,SQL Server不支持批处理执行情况下的getGeneratedKeys()。

这里是不满意的function请求: https : //github.com/Microsoft/mssql-jdbc/issues/245

我的build议是,如果由于某种原因,你的第三个服务器批量插入被执行,这可能会导致你提到的exception(在其他两个只有一个项目被插入的情况下)

你可以尝试loggingsql语句来检查这个