В чем дело?

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

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


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


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