Есть ли параметр для предотвращения длинных транзакций? Я хочу автоматически откатывать все транзакции, которые занимают более 5 минут. Это возможно? Я работаю над Microsoft SQL Server 2008 R2.
Справочная информация:
Я спрашиваю об этом, потому что я работаю со многими ужасными приложениями: в случае исключения приложения они показывают модальное предупреждение, транзакция освобождается ТОЛЬКО при закрытии предупреждения. Я действительно знаю, что это кажется шуткой, но это не так! Я не могу изменить это приложение, и я не могу уволить их разработчиков, но мне нужно решить эту проблему: длительная транзакция (также может быть простой транзакцией с низкой стоимостью) должна занимать менее 5 минут. В противном случае некоторые таблицы будут заблокированы до закрытия модального окна.
Существует опция под названием «ограничение стоимости регулятора запросов», которая принимает целочисленное значение. Указываемое вами значение - это максимальное время в секундах, в течение которого может выполняться запрос. Обратите внимание, что это основано на расчетном времени и стоимости. Если стоимость превышает это, запрос НЕ будет разрешен к выполнению. Это не точная наука, некоторые могут работать дольше, а некоторые, которые запрещены, могут работать короче, поскольку это основано на оценочной стоимости.
http://technet.microsoft.com/en-us/library/ms190419(v=sql.105).aspx
Возможно, вам будет интересна эта другая ветка StackOverflow:
Ограничьте ресурсы, доступные для запроса в SQL Server
https://stackoverflow.com/questions/9336194/limit-resources-available-to-query-in-sql-server
Это мой временный ответ:
DECLARE @ProcessId int=null;
SELECT top 1 @ProcessId=p.spid
--, s.host_name, s.program_name, s.original_login_name, q.text as sql, wp.spid as waiting_sess, ws.host_name as waiting_host_name, ws.program_name as waiting_program_name, wr.wait_time as waiting_time, wq.text as waiting_sql
FROM sys.sysprocesses p
join sys.dm_exec_sessions s on s.session_id=p.spid
join sys.dm_exec_connections c on c.session_id=p.spid
CROSS APPLY sys.dm_exec_sql_text(c.most_recent_sql_handle) AS q
join sys.sysprocesses wp on wp.blocked=p.spid
join sys.dm_exec_sessions ws on ws.session_id=wp.spid
join sys.dm_exec_requests wr on wr.session_id=wp.spid
CROSS APPLY sys.dm_exec_sql_text(wr.sql_handle) AS wq
WHERE p.spid in (select distinct blocked FROM sys.sysprocesses where blocked>0)
and p.blocked<=0
and wr.wait_time>300000 --5min
-- uncomment the next line to really kill process
-- if @ProcessId is not null EXEC('KILL ' + @ProcessId);
Это запрос для получения всего процесса блокировки с ресурсом ожидания> 5 минут (300000 миллисекунд). После этого он выполняет kill с этим pid. Я запланирую эту хранимую процедуру с помощью агента сервера Sql.