В чем дело?

Всем Привет!По поводу моей проблемы.В двух словах о ней:Программа на делфи-стартует транзакцию-запускает хранимую процедуру с передачей туда параметров Хранимая процедура -получает параметры -открывает курсор с этими параметрами -делает цикл по курсору -закрывает курсор и выходит обратно в делфи-завершает транзакцию.Все очень просто. Временами такой алгоритм зависал на -открывает курсор с этими параметрамиПричем кто держит селект курсора и почему, никак нельзя было посмотреть.В различных мониторах показывалось, что естественно установила какие-тоблокировки на объекты, но никаких взаимоблокировок с другими сессияминет, никто никого не блокирует. Причем если запустить этот запрос,который образует курсор, отдельно, то запрос отрабатывает, что означает,что таблицы входящие в запрос не заблокированы. Проблему решал простой перезагрузкой сервера.Потом решил сделать переделать хранимую процедуру: Хранимая процедура -получает параметры -создает временную таблицу -вставляет во временную таблицу данные по запросу с этимипараметрами -открывает курсор по временной таблице -делает цикл по курсору -закрывает курсор -выходит обратно в делфи (временная таблица уничтожаетсяавтоматически)С этим вариантом зависания продолжаются и происходит на -вставляет во временную таблицу данные по запросу с этимипараметрамиТ.е. зависания упорно продолжаются если запрос с этими таблицамипроисходит внутри процедурыТогда я перенес часть кода из процедуры в делфи, для этого создалпромежуточную таблицу. Все стало выглядеть таким образом:Программа на делфи-стартует транзакцию-удаляем старые данные из промежуточной таблицы (котрые были вчера)-вставляет в промежуточную таблицу данные по запросу с параметрами-запускает хранимую процедуру Хранимая процедура -открывает курсор по промежуточной таблице -делает цикл по курсору -закрывает курсор и выходит обратно в делфи-завершает транзакцию.Это вроде работает. Запускали одновременно с разных машин и никакихблокировок не было.Я не понимаю почему первые два варианта неработают, а последнийработает. Очевидно, что блокировка происходит при работе запроса внутрипроцедуры, а с наружи запрос работает нормально. В чем тут может бытьдело? Хотя бы теоритически...PS:-Использовалась связка Delphi5+BDE+SQL2000Уровень изоляции ReadCommited-Запрос образующий курсор использует view, которые в свою очередь тожесодержат в себе view-ПЕРВОНАЧАЛЬНЫЙ КОД ПРОЦЕДУРЫ (НА ТО ЧТО ВНУТРИ ЦИКЛА МОЖНО ВНИМАНИЯ НЕОБРАЩАТЬ ДО ЭТОГО ДЕЛО ДАЖЕ НЕ ДОХОДИТ)
ALTER PROCEDURE r_CreateDocDopFrmMISSProf
@idcln int,
@profilenam varchar(<b>50</b>),
@iddep int, <i>--не используется
</i>@datbeg varchar(<b>10</b>),
@datend varchar(<b>10</b>),
@chkExcise int, <i>--0 -акциз не вычитать, 1 -акциз вычитать
</i>@idoper int

AS

IDClient='+RTRIM(LTRIM(STR(@idcln)))+' Profile='+@profilenam+'
IDDep='+RTRIM(LTRIM(STR(@iddep)))+' IDOper='+RTRIM(LTRIM(STR(@idoper))))

DECLARE
 @payer varchar(50), @contract varchar(50), @tovar_id int,
 @prod varchar(50), @pack varchar(20),@idclient int,@idper
int,
 @idfactory varchar(10),@factory varchar(50), @iddir
varchar(10), @dir varchar(50), @dat datetime,
 @prc float, @clrprc float, @var_num varchar(50),
 @flg int, @otgr varchar(10), @NewDoc int, @prcval float,
 @dbeg datetime, @dend datetime

DECLARE @num varchar(30),@d datetime, @iddoc int,
 @idprod int, @idprotmiss int,
 @idt int, @idtypprod int, @idfact int, @idpoint int,
 @iddirect int, @idtariff int, @dd datetime

SELECT @NewDoc=0
SELECT @dbeg=CONVERT(datetime,@datbeg,104)
SELECT @dend=CONVERT(datetime,@datend,104)

--************************************************
DECLARE cur12 CURSOR FOR
	SELECT DISTINCT
		t.payer,t.contract,t.tovar_id,t.prod,t.pack,

t.idfactory,t.factory,t.iddir,t.dir,t.dat,t.prc,t.clrprc,
		t.var_num,t.flg,
		otgr=case when isnull(tt.idr3contr,'*')='*' then 'Нет'
else 'Да' end
	FROM
		(SELECT DISTINCT r.*
		FROM
			(SELECT
				contract,
				tovar_id,
				factory,
				dir,
				dat,
				MAX(flg) flg
			FROM r_firmprodprotmissprof WITH (READPAST)
			WHERE prof=@profilenam
			GROUP BY
				contract,
				tovar_id,
				factory,
				dir,
				dat) t,
			r_firmprodprotmissprof r WITH (READPAST)
		WHERE
			r.prof=@profilenam AND
			r.contract=t.contract AND
			r.tovar_id=t.tovar_id AND
			r.factory=t.factory AND
			r.dir=t.dir AND
			r.dat=t.dat AND
			r.flg=t.flg AND
			r.idfactory in('A2','03','04','02','05','15')
		) t,
		r_firmprodplanprof tt WITH (READPAST)
	WHERE
		tt.prof=@profilenam AND
		t.contract=tt.idr3contr AND
		t.tovar_id=tt.idtovar AND
		tt.id_department ELSE @iddep END AND
		tt.id_client=CASE
			WHEN @idcln=-1 THEN tt.id_client ELSE @idcln END
AND
		t.dat BETWEEN @dbeg AND @dend
	ORDER BY t.contract,t.dat,t.var_num
	FOR READ ONLY
--*************************************************


 SELECT @num='';
 SELECT @d=CONVERT(DATETIME,'01.<b>01</b>.<b>1900</b>',<b>104</b>)
 SELECT @iddoc=-<b>1</b>
 SELECT @idclient=-<b>1</b>
 SELECT @dd=GETDATE()

	OPEN cur12
	FETCH NEXT FROM cur12 INTO
@payer,@contract,@tovar_id,@prod,@pack,@idfactory,@factory,
@iddir,@dir,@dat,@prc,@clrprc,@var_num,@flg,@otgr
	WHILE (@@FETCH_STATUS)=<b>0</b>
	BEGIN
		...
		...
		...

	 FETCH NEXT FROM cur12 INTO
@payer,@contract,@tovar_id,@prod,@pack,@idfactory,
@factory,@iddir,@dir,@dat,@prc,@clrprc,@var_num,@flg,@otgr
	END

	CLOSE cur12
	DEALLOCATE cur12
3 ответа

Одного не понял совсем (т.е. я много чего не понял, но это уж совсем не понял - блин - даже не понял, что сказал)ЛадноВопрос у меня такой:А зачем транзакцию открывать на клиенте, если в нее все одно только 1 процедура входит?Что в процедуре не судьба?


Из рекомендаций. Раз уж вы написали хп, то и транзакциями управляйте в хп, а не с клиента. Поставьте первой строчкой хп SET NOCOUNT ON.
Причем кто держит селект курсора и почему, никак нельзя было посмотреть.
т.е. sp_who не запускали?


Алгоритм работы который я привел -немного упрощенный. Вынести управление транзацией в процедуру нельзя. Там после отработки процедуры еще некоторые задачи на клиенте отрабатывают, т.е решение о том: сохранять изменения или нет решает оператор. Процедура ему что-то расчитает и выдаст какие-то данные, на клиенте эти данные отобразятся, оператор на них посмотрит и либо завершает транзакцию, либо отменяет. Понятно, что держать открытую транзакцию на клиенте это нехорошо, но это так сделано и что либо менять сложно.Процедуру sp_who запускал. Клиентская сессия там видна со статусом runable и командой OpenCursor. Смотрел еще sp_lock, sysprocesses. Ничего подозрительного не увидел. Просто видно, что клиентская сессия создала свои блокировки на используемые объекты и все. Другие сессии ее не блокируют.Что может дать SET NOCOUNT ON