Программа создаёт блокировки и процессы которые висят. Помогает завершение процессов с помощью T-SQL. Но есть проблема, вместе с этим завершаются нужные процессы, в следствии чего набранные данные не сохраняются(было замечено несколько раз) или при работе в другом окне программы завершается процесс главной формы.
DECLARE @v_spid INT
DECLARE c_Users CURSOR
FAST_FORWARD FOR
SELECT SPID
FROM master..sysprocesses (NOLOCK)
WHERE spid>50
AND status='sleeping'
AND DATEDIFF(mi,last_batch,GETDATE())>=5
AND spid<>@@spid
OPEN c_Users
FETCH NEXT FROM c_Users INTO @v_spid
WHILE (@@FETCH_STATUS=0)
BEGIN
PRINT 'KILLing '+CONVERT(VARCHAR,@v_spid)+'...'
EXEC('KILL '+@v_spid)
FETCH NEXT FROM c_Users INTO @v_spid
END
CLOSE c_Users
DEALLOCATE c_Users
Ответ
Нехорошо убивать процессы, не выяснив причину. Тем более, что sleeping означает ожидание сервером запроса от клиента, а под это условие могут быть квалифицированы сессии в совершенно разном логическом состоянии.
У сессии может быть открытая транзакция и она может быть в состоянии sleeping между отдельными командами, а может не быть открытых транзакций - например, клиент просто подсоединился к серверу, или клиент подсоединился и сделал запрос, а соединение не закрыл (скоро опять понадобится).
процессы которые висят
Вам лучше расследовать ситуацию. Иногда бывает достаточно sp_who, sp_who2 и sp_lock
Основные причины подвисания процесса при запросе, как правило:
запрос никто не блокирует, он долгий сам по себе
запрос долгий, потому что он блокируется чем-то
другим запросом
пользовательской транзакцией
Поищите сессии, делающие долгие запросы
SELECT
s.session_id,
r.total_elapsed_time,
r.wait_time,
r.wait_type,
r.wait_resource,
r.blocking_session_id
FROM
sys.dm_exec_sessions s
JOIN sys.dm_exec_requests r ON r.session_id = s.session_id
WHERE
s.is_user_process = 1 AND s.session_id != @@SPID
ORDER BY
r.total_elapsed_time DESC;
Если сессия блокирована кем-то, то вы увидите идентификатор сессии в blocking_session_id
Потом уже по конкретной сессии можно посмотреть что в ней происходит вплоть до текста и плана конкретно выполняющейся в данный момент команды:
SELECT
r.session_id,
t.text,
p.query_plan,
stmt_text =
SUBSTRING(
t.text,
r.statement_start_offset / 2 + 1,
(CASE r.statement_end_offset WHEN -1 THEN DATALENGTH(t.text) ELSE r.statement_end_offset END - r.statement_start_offset) / 2 + 1
),
stmt_plan = CAST(stp.query_plan AS xml)
FROM
sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_query_plan(r.plan_handle) p
CROSS APPLY sys.dm_exec_sql_text(r.plan_handle) t
CROSS APPLY sys.dm_exec_text_query_plan(r.plan_handle, r.statement_start_offset, r.statement_end_offset) stp
WHERE
r.session_id = @sessionID;
Поискать сессии с незавершенными транзакциями можно, например, так:
SELECT
s_tr.session_id,
a_tr.transaction_id,
open_time_msec = DATEDIFF(millisecond, a_tr.transaction_begin_time, GETDATE())
FROM
sys.dm_tran_session_transactions s_tr
JOIN sys.dm_tran_active_transactions a_tr ON a_tr.transaction_id = s_tr.transaction_id
WHERE
s_tr.is_user_transaction = 1 AND s_tr.session_id != @@SPID
ORDER BY
a_tr.transaction_begin_time;
Комментариев нет:
Отправить комментарий