【问题标题】:SQL Server / JDBC Connectivity IssuesSQL Server / JDBC 连接问题
【发布时间】:2009-09-28 00:10:48
【问题描述】:

我在我的 Java 服务器应用程序中遇到了一些奇怪的行为,通常需要几毫秒的数据库操作偶尔会花费更长的时间(30 到 170 秒)才能完成。这并不孤立于特定查询,因为我已经看到 SQL 更新和选择语句都发生延迟。此外,我所有的 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)

【问题讨论】:

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


    【解决方案1】:

    "...由此数据库操作 通常需要几毫秒 偶尔需要更长的时间(30s - 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)。

    【讨论】:

    • Mitch,目前这些表非常小,即使是不正确的查询(即表扫描)也可以忽略不计。所以我更倾向于认为备份作业(或其他)可能会导致服务器资源消耗。不幸的是,它是一个共享的生产服务器,因此很难追查任何罪魁祸首。
    【解决方案2】:

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

    【讨论】:

    • " 数据库是否在单独的机器上?" - 他们通常是! :)
    • 是的,它在另一台机器上(尽管我的开发者不是!)。过去,Management Studio 中不会消失的“传输级别错误”(即,如果我从 IDE 重新运行查询)表明存在网络问题。但是,当我重新运行相同的查询时,这个错误就会消失,所以我想知道这是否更多地指向资源问题。
    猜你喜欢
    • 2014-08-04
    • 1970-01-01
    • 2019-03-13
    • 1970-01-01
    • 2013-04-13
    • 2017-10-17
    • 2014-12-01
    • 2010-11-19
    相关资源
    最近更新 更多