我们在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次。 (由服务器3处理的4500)大多数时候查询在服务器3上也能很好地工作。有时,每天说20次,查询失败。始终是相同的查询,始终是相同的服务器。从来没有其他服务器。
我们尝试了什么
PreparedStatements
是否都是使用PreparedStatement.RETURN_GENERATED_KEYS
参数构建的。看起来这是与服务器配置相关的一些问题,因为docker镜像都是一样的。但我们找不到原因。有没有人有什么建议可以解决问题?或者有没有人遇到过这个问题?
答案 0 :(得分:0)
据我所知,SQL Server不支持批处理执行时的getGeneratedKeys()。
以下是尚未满足的功能请求:https://github.com/Microsoft/mssql-jdbc/issues/245
我的建议是,如果由于某种原因你第三次服务器批量插入被严格执行,这可能导致你提到的异常(如果其他两个只插入了一个项目)
您可以尝试记录sql语句以检查此