我在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)
答案 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。数据库是在一台单独的机器上吗?