SQL Server / JDBC连接问题

时间:2009-09-28 00:10:49

标签: java sql sql-server jdbc sql-server-2000

我在Java服务器应用程序中遇到了一些奇怪的行为,通常需要花费几毫秒的数据库操作需要花费更长的时间(30s-170s)来完成。这不是特定查询的隔离,因为我已经看到SQL更新和select语句都发生了延迟。此外,我的所有select语句都使用NOLOCK选项,因此我排除了可能的锁争用。

我最后一次看到延迟时,设法从JConsole捕获以下堆栈跟踪;有问题的更新通常需要5毫秒才能完成,但是这个堆栈跟踪至少可以访问10到20秒。跟踪告诉我该语句已被执行但是检索结果有一些延迟,虽然我可能是错的?显然,因为这是一个更新语句,我期望的唯一结果是行计数(即不是一个大的数据结果集)。

在延迟时,我在SQL Server Management Studio中看到了“传输级别错误”。

我遇到的一个建议是,这些问题是由于SQL Server资源耗尽造成的。有没有人见过类似的东西?任何人都可以解释这个问题吗?

提前致谢。

堆栈追踪:

Name: MessageRouterImplThread-2
State: RUNNABLE
Total blocked: 0  Total waited: 224

Stack trace: 
java.net.SocketInputStream.socketRead0(Native Method)
java.net.SocketInputStream.read(SocketInputStream.java:129)
com.microsoft.util.UtilSocketDataProvider.getArrayOfBytes(Unknown Source)
com.microsoft.util.UtilBufferedDataProvider.cacheNextBlock(Unknown Source)
com.microsoft.util.UtilBufferedDataProvider.getArrayOfBytes(Unknown Source)
com.microsoft.jdbc.sqlserver.SQLServerDepacketizingDataProvider.signalStartOfPacket(Unknown Source)
com.microsoft.util.UtilDepacketizingDataProvider.getByte(Unknown Source)
com.microsoft.util.UtilByteOrderedDataReader.readInt8(Unknown Source)
com.microsoft.jdbc.sqlserver.tds.TDSRequest.getTokenType(Unknown Source)
com.microsoft.jdbc.sqlserver.tds.TDSRequest.processReply(Unknown Source)
com.microsoft.jdbc.sqlserver.SQLServerImplStatement.getNextResultType(Unknown Source)
com.microsoft.jdbc.base.BaseStatement.commonTransitionToState(Unknown Source)
com.microsoft.jdbc.base.BaseStatement.postImplExecute(Unknown Source)
com.microsoft.jdbc.base.BasePreparedStatement.postImplExecute(Unknown Source)
com.microsoft.jdbc.base.BaseStatement.commonExecute(Unknown Source)
com.microsoft.jdbc.base.BaseStatement.executeUpdateInternal(Unknown Source)
com.microsoft.jdbc.base.BasePreparedStatement.executeUpdate(Unknown Source)
   - locked com.microsoft.jdbc.sqlserver.SQLServerConnection@c4b83f
org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:101)
org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement(JdbcTemplate.java:798)
org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:591)
org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:792)
org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:850)
org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:858)
org.springframework.jdbc.core.simple.SimpleJdbcTemplate.update(SimpleJdbcTemplate.java:237)

2 个答案:

答案 0 :(得分:1)

  

“...即数据库操作   通常需要几毫秒   偶尔花费更长时间(30秒 -   170年代)完成。“

由于过时的统计信息(和/或需要重建的索引)或不正确的参数嗅探,您所描述的内容听起来像是错误缓存的查询计划。超时可能发生,因为服务器占用的时间超过了默认的连接超时。

我会与您的DBA交谈并首先更新统计信息,如果这不起作用,请重新构建查询中涉及的表的索引。

在您的数据库上运行此操作(通常需要注意的是不在生产中运行而不与您的管理员/ DBA交谈,并自行承担风险等)。

EXEC sp_updatestats

EXEC sp_refreshview 

EXEC sp_msForEachTable 'EXEC sp_recompile ''?''' 

或者,你提到时间是一个因素。可能是那时正在进行备份或预定作业吗?

更新:您可以启动探查器跟踪:MS SQL Server 2008 - How Can I Log and Find the Most Expensive Queries?但不限制您的数据库。只要根据该帖子从SSMS开始,这样的痕迹影响相对较小(3-5%ish)。

答案 1 :(得分:1)

“传输级别错误”似乎表示connectivity problems。数据库是在一台单独的机器上吗?