2009-09-28 1 views
1

Я испытываю странное поведение в своем приложении Java-сервера, в результате чего операции базы данных, которые обычно занимают несколько миллисекунд, периодически заполняются дольше (30 с-170). Это не связано с конкретным запросом, так как я видел задержки, возникающие как для операторов SQL, так и для выбора. Кроме того, все мои операторы select используют параметр NOLOCK, поэтому я исключил возможность блокировки.Проблемы с подключением SQL Server/JDBC

Последний раз, когда я видел задержку, мне удалось захватить следующую трассировку стека от 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 [email protected] 
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) 

ответ

1

"... причем операции с базами данных, которые обычно занимает несколько миллисекунд спорадически занимает гораздо больше времени (30-е годы - 170S), чтобы закончить."

То, что вы описываете, звучит как неверно кэшированный план запросов из-за устаревшей статистики (и/или индексов, требующих перестройки), или неправильного нюхания параметров. Тайм-аут может возникнуть, потому что сервер занимает больше времени, чем время ожидания соединения по умолчанию.

Я бы поговорил с вашим администратором базы данных и сначала обновил статистику, и если это не поможет получить индексы таблиц, участвующих в запросе, перестроен.

Выполнить это на базы данных (с обычной оговоркой о не runninhg в производстве, не посоветовавшись с админ/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% иш).

+0

Mitch, В настоящее время таблицы настолько малы, что даже неправильный запрос (то есть сканирование таблицы) будет небрежным. Поэтому я склонен думать, что задание резервного копирования (или что-то еще) может вызвать утечку ресурсов сервера. К сожалению, это совместный производственный сервер, поэтому любому преступнику будет сложно отследить. – Adamski

+0

@Adamski: возможно, вы могли бы запустить след. Я уточню свой ответ с подробностями ... –

1

«Ошибка уровня транспортного уровня», как представляется, указывает connectivity problems. Является ли база данных отдельной машиной?

+2

«Является ли база данных на отдельной машине?» - они обычно есть! :) –

+0

Да, это на отдельной машине (хотя мой dev один нет!). В прошлом «ошибка транспортного уровня» в Management Studio, которая не исчезнет (т. Е. Если я повторю запрос из IDE), свидетельствует о сетевой проблеме. Однако эта ошибка уходит, когда я повторно запускаю тот же запрос, поэтому мне интересно, не указывает ли это больше на проблему с ресурсами. – Adamski