我有一个很好奇的案子。
我怎么能com.microsoft.sqlserver.jdbc.SQLServerException: Lock request time out period exceeded.上getMoreResults()?什么可能导致这种情况?
堆栈跟踪:
...
原因:com.microsoft.sqlserver.jdbc.SQLServerException:超过锁定请求超时期限。
在 com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:197)
在 com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1493)
在 com.microsoft.sqlserver.jdbc.SQLServerStatement.getMoreResults(SQLServerStatement.java:1191)
在 org.apache.tomcat.dbcp.dbcp.DelegatingStatement.getMoreResults(DelegatingStatement.java:270)
在 org.apache.tomcat.dbcp.dbcp.DelegatingStatement.getMoreResults(DelegatingStatement.java:270)
在 org.springframework.jdbc.core.JdbcTemplate.extractReturnedResults(JdbcTemplate.java:1045)
在 org.springframework.jdbc.core.JdbcTemplate$5.doInCallableStatement(JdbcTemplate.java:988)
在 org.springframework.jdbc.core.JdbcTemplate$5.doInCallableStatement(JdbcTemplate.java:1)
在 org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:928)
... 34 更多
JdbcTemplate 代码如下所示:
返回执行(csc,新的CallableStatementCallback>(){
公共映射 doInCallableStatement(CallableStatement cs) 抛出 SQLException {
布尔 retVal = cs.execute();
int updateCount = cs.getUpdateCount();
if (logger.isDebugEnabled()) {
logger.debug("CallableStatement.execute() 返回 '" + retVal + "'");
logger.debug("CallableStatement.getUpdateCount() 返回" + updateCount);
}
映射返回结果 = createResultsMap();
if (retVal || updateCount != -1) {
returnedResults.putAll(extractReturnedResults(cs, updateCountParameters, resultSetParameters, updateCount));
}
返回结果.putAll(extractOutputParameters(cs, callParameters));
返回返回的结果;
}
});
cs.execute()以这种方式调用存储过程
exec sp_prepexec @p1 output,N'@P0 int,@P1 int',N'exec my_sproc @P0,@P1', 1, 2
该调用成功,并且在调用该方法之后extractReturnedResults()。它使用 getMoreResults()。第一次迭代成功,第二次出现异常。它发生在我的生产系统上,我无法再次重现它。存储过程本身并没有抛出锁超时,因为代码被包装在 try/catch 中。只是为了仔细检查我已经删除了 try/catch 阻塞、模拟锁定超时,并且我在调用时收到了异常execute()- 这是有道理的。这就像在存储过程执行之后和打印结果集中间发生的锁定超时?我只在 try/catch 块中定义了 lock_timeout。我没有在 jdbc 连接字符串中设置 queryTimeout 或类似的东西?
另一种理论是网络带宽在那个精确的时刻(在成功调用存储过程之后和打印结果集的中间)是满的。该理论的问题在于我没有设置任何其他超时。