SQL 2000 - чудеса с незакрывающейся транзакцией

vovap
Уже с Приветом
Posts: 12014
Joined: 05 Apr 2000 09:01
Location: Philadelphia, PA, USA

SQL 2000 - чудеса с незакрывающейся транзакцией

Post by vovap »

Возникла у нас проблемма с аппликатион. Путем включения всех возможных логов выяснено - проблемма происходит вследствии незакрытой транзакции.
Все хорошо, одна беда - не могу понять, почему транзакция не закрывается и как такое возможно.
Нашел я значит по логам место где оноа вроде создается. Происходит это в сторед процедуре, которая вызывается из другой сторед процедуры. Схема там простая:
BEGIN TRANSACTION
statement1
..
statementN
COMMIT RANSACTION

В вызывающей процедуре тоже есть транзакция, но они не пересекаются.
По логу я виже - BEGIN TRANSACTION прошло, statement1 пошел, statement1 завершен.
До statement2 дело не доходит - судя по всему произошел ADO SQL tymeout - как раз прошло 30 секунд с начала выполнения всей команды а таймоут там дефолт не меняли.
Выбрасывается событие завершения сторед процедуры. Потом - событие Attention. Закрытия транзакции не происходит и с этого моментя она (вроде она - время и процесс совпадают) висит открытая.
Причем DBCC OPENTRAN возвращает к этой транзакции user ID =-1 - и шо это значит?
Тут я вообще задумался - а что происходит, когда срабатывает ADO SQL tymeout на SQL derver?
Причем воспроизвести это (иногда) удается только на 4 процессорном продакшин SQL бохе (SQL server 2000 SP3) - на тестовом однопроцессорном - никак.
Сама команда выполняется через ADO как Connection.execute(). Параметры все дефолт. Версию ADO не знаю - объект создается из дефолт.
Что кто может сказать мудрого?
User avatar
Dmitry67
Уже с Приветом
Posts: 28294
Joined: 29 Aug 2000 09:01
Location: SPB --> Gloucester, MA, US --> SPB --> Paris

Post by Dmitry67 »

В 6.5 были проблемы
У нас даже висел процесс которые мертвые транзакции убивал
За 2000 такого поведения не видел
А у вас connection pool есть ?
Зарегистрированный нацпредатель, удостоверение N 19719876044787 от 22.09.2014
vovap
Уже с Приветом
Posts: 12014
Joined: 05 Apr 2000 09:01
Location: Philadelphia, PA, USA

Post by vovap »

Dmitry67 wrote:В 6.5 были проблемы
У нас даже висел процесс которые мертвые транзакции убивал
За 2000 такого поведения не видел
А у вас connection pool есть ?

Нету. Для каждой команды коннекшин создается заново. Правда все это делается в COM+ но я и так соображал и эдак - не вижу как коннетион может быть реюз.
Интуиция мне подсказывает - что то с ADO - но далше она не говорит :)
Да, еще что удивляет - что время жизни процессов частенько значительно больше 30 секунд таймоута. Отчего сие? Наскока понимаю новая коннекшин должна создавать новый процесс?
User avatar
Dmitry67
Уже с Приветом
Posts: 28294
Joined: 29 Aug 2000 09:01
Location: SPB --> Gloucester, MA, US --> SPB --> Paris

Post by Dmitry67 »

А что про транзакцию говорит select * from sysprocesses ?
Зарегистрированный нацпредатель, удостоверение N 19719876044787 от 22.09.2014
vovap
Уже с Приветом
Posts: 12014
Joined: 05 Apr 2000 09:01
Location: Philadelphia, PA, USA

Post by vovap »

Dmitry67 wrote:А что про транзакцию говорит select * from sysprocesses ?

А что sysprocesses? Иногда и процесса уге такого нет или ест, но другоы.
Исследоване показало что сп как:
-------------------------------------------------------------
CREATE PROCEDURE [vp_TestTran]
AS

CREATE TABLE #Temp (Temp1 INT)
BEGIN TRANSACTION
INSERT #Temp (Temp1) values(10)
WAITFOR DELAY '00:00:40'
COMMIT TRANSACTION
GO
-------------------------------------------------------------
Воцпроисводит ситуатион. АДО делает тимеоут а трансактсия остаетсиа минут на 3-5 при еденичном записке.
А если посилат новие запроси на исполнение того ге - то и долше. Причем даге когда старая убизаетсиа и ее замениает другая - номер процесса тот ге.
dbcc opentran ('tempdb') дает:
Transaction information for database 'tempdb'.
Oldest active transaction:
SPID (server process ID) : 59
UID (user ID) : -1
Name : user_transaction
LSN : (751:375:517)
Start time : Jan 22 2004 12:27:42:690PM
vovap
Уже с Приветом
Posts: 12014
Joined: 05 Apr 2000 09:01
Location: Philadelphia, PA, USA

Post by vovap »

Упдате - вот как виглиаит видержка select * from sysprocesses:
spid login_time last_batch open_tran
59 13:01:02 13:05:54 0 10

Oldest active transaction:
SPID (server process ID) : 59
UID (user ID) : -1
Name : user_transaction
LSN : (856:184:361)
Start time : Jan 22 2004 1:01:01:923PM

Ето если посилати запрос етоы СП черес АДО и далее.

Как видно процесс гивет уге почти 5 минут (тимеоут -то 30 сек) и защитал себе все трансактсии с самого начала - хотиа кажды рас откриваетсиа новая коннецтион и трансактсия в СП одна.
User avatar
Dmitry67
Уже с Приветом
Posts: 28294
Joined: 29 Aug 2000 09:01
Location: SPB --> Gloucester, MA, US --> SPB --> Paris

Post by Dmitry67 »

Сохранение нового @@spid совершенно нормально
Я видел что у Вас open_tran=0
Почему Вы считаете что locks Идут от этой транзакции ?
Зарегистрированный нацпредатель, удостоверение N 19719876044787 от 22.09.2014
chekur13
Новичок
Posts: 30
Joined: 09 Feb 2002 10:01
Location: Kharkov, Ukraine

Post by chekur13 »

Нечто подобное обсуждалось на sql.ru
http://www.sql.ru/forum/actualthread.aspx?bid=1&tid=40063&pg=-1
vovap
Уже с Приветом
Posts: 12014
Joined: 05 Apr 2000 09:01
Location: Philadelphia, PA, USA

Post by vovap »

Dmitry67 wrote:Сохранение нового @@spid совершенно нормально
Я видел что у Вас open_tran=0
Почему Вы считаете что locks Идут от этой транзакции ?

Не там open_tran=10, нолик это другая колонка.
Да вроде разобрался более - менее. Родимое ADO, конечно. Оно делает коннектион пулинг. Ну так как коннект не закрывается - то сервер и не освобождает ресурсы - ни транзакции, ни локи. Все это навешивается на следующий колл. И так далее.
Щас пытаюсь понять, кто же, собственно делает этот пулинг -IIS или OLE DB Provider и как избавиться. Коннектион оъект создается там как CreateObject() из COM+ сомпонента, а тот вызывается с ASP страници.
Причем если создавать коннект на самой странице и там юзать, то даже
conn.close
set conn = Nothing
воспринимается не более чем шутка а не руководство к действию.
Seryi
Ник закрыт как дубликат.
Posts: 6238
Joined: 14 Mar 2001 10:01
Location: .MD -> .SI -> .SE -> .AR.US -> .MD

Post by Seryi »

Disabling Connection Pooling

http://support.microsoft.com/default.as ... bContent=1

'For SQLOLEDB provider
'strConnect = "Provider=SQLOLEDB;server=SQL7Web;OLE DB Services = -2;uid=AppUser;pwd=AppUser;initial catalog=northwind"

' For MSDASQL provider
'strConnect = "DSN=SQLNWind;UID=Test;PWD=Test; OLE DB Services= -2"

ключевое слово OLE DB Services=-2
vovap
Уже с Приветом
Posts: 12014
Joined: 05 Apr 2000 09:01
Location: Philadelphia, PA, USA

Post by vovap »

Seryi wrote:ключевое слово OLE DB Services=-2

Да, спасибо, это работает прекрасно. Хотя ресурся сразу и не освобождаются, но процесс уже не реюзается и снежного кома навешивания на него ресурсов не происходит.
Все бы прекрасно, но при этом отказывается работать msDataShape. А мы его юзаем. Вякает сразу (еще при открытии коннекта) что мултипле степ OLE DB операция привела к шибко печальным последствиям.
Черт возьми. Ну так же не бывает. Один из нас идиот - или я, или Microsoft.
Не может же это так работать штатно. Почему когда я закрываю коннект из VB программы - ресурсы освобождаются сей момент как закрывается коннект, а то же самое из COM+ компонента, вызываемого с ASP страници - тока минуты через полторы в луцшем случае. В чем дело? И как заставить скотину закрывать все сразу? Не может же быть, чтобы я первый на это набрел - архитекрура - то классическая.
Может тут какие сетевые проблеммы? Как вообще физически поддерживается коннект и что происходит, когда закрывается?
NNemo
Уже с Приветом
Posts: 1935
Joined: 15 Sep 2003 17:49
Location: Ukraine, Mariupol -> USA everywhere :-)

Post by NNemo »

А компонент у вас не пулится часом? Может референс где-то остается.
У COM+ свои таймауты.
Нужно позвать мeтоды контекста или что там у вас используется, это принудит COM+ разрушить или поместить компонент в пул. Если пулится, то нужно это правильно реализовать. IObjectControl насколько я припоминаю.
vovap
Уже с Приветом
Posts: 12014
Joined: 05 Apr 2000 09:01
Location: Philadelphia, PA, USA

Post by vovap »

NNemo wrote:А компонент у вас не пулится часом? Может референс где-то остается.
У COM+ свои таймауты.
Нужно позвать мeтоды контекста или что там у вас используется, это принудит COM+ разрушить или поместить компонент в пул. Если пулится, то нужно это правильно реализовать. IObjectControl насколько я припоминаю.

Ну даже если компонент пулится, то я ведь в одном методе открываю коннект, шлю SQL, закрываю коннект и сет его носинг. Усе. Никаких референсов на уровне объекта - в сущности обычная функция. Почему эта скотина не желает закрыться, если я его явно закрываю и уничтожаю?
Seryi
Ник закрыт как дубликат.
Posts: 6238
Joined: 14 Mar 2001 10:01
Location: .MD -> .SI -> .SE -> .AR.US -> .MD

Post by Seryi »

vovap, вот подробная статья про Connection Pooling, почитайте возможно найдется ответ
http://msdn.microsoft.com/library/defau ... oling2.asp
vovap
Уже с Приветом
Posts: 12014
Joined: 05 Apr 2000 09:01
Location: Philadelphia, PA, USA

Post by vovap »

Seryi wrote:vovap, вот подробная статья про Connection Pooling, почитайте возможно найдется ответ
http://msdn.microsoft.com/library/defau ... oling2.asp

Спасибо, я это уже находил. Попробую еще посмотреть. Старая только - это еще про ADO 2.
Попробую поискать инфу по более глубокому механизму коннекта. Есть у меня подозрения к сетевому уровню.
NNemo
Уже с Приветом
Posts: 1935
Joined: 15 Sep 2003 17:49
Location: Ukraine, Mariupol -> USA everywhere :-)

Post by NNemo »

vovap wrote:
NNemo wrote:А компонент у вас не пулится часом? Может референс где-то остается.
У COM+ свои таймауты.
Нужно позвать мeтоды контекста или что там у вас используется, это принудит COM+ разрушить или поместить компонент в пул. Если пулится, то нужно это правильно реализовать. IObjectControl насколько я припоминаю.

Ну даже если компонент пулится, то я ведь в одном методе открываю коннект, шлю SQL, закрываю коннект и сет его носинг. Усе. Никаких референсов на уровне объекта - в сущности обычная функция. Почему эта скотина не желает закрыться, если я его явно закрываю и уничтожаю?


А что из функции возвращается? Не рекордсет часом в другой слой?
Может он тоже референс на коннекцию держит? Они поди на одном сервере все живут... Кто его знает как там MS cсылки посчитал?
vovap
Уже с Приветом
Posts: 12014
Joined: 05 Apr 2000 09:01
Location: Philadelphia, PA, USA

Post by vovap »

NNemo wrote:.
А что из функции возвращается? Не рекордсет часом в другой слой?
Может он тоже референс на коннекцию держит? Они поди на одном сервере все живут... Кто его знает как там MS cсылки посчитал?

Нет, не рекордсет. То, что меня интересует, это update -insert процедуры.
vovap
Уже с Приветом
Posts: 12014
Joined: 05 Apr 2000 09:01
Location: Philadelphia, PA, USA

Post by vovap »

Да, так вот что удалось в конце концов выяснить.
1. ADO делает коннектион пул по умолчанию всегда.
2. Если используется SQLOLEDB провайдер для коннекта - то он, перед использованием коннекта из пула выполняет sp_reset_connection - внутреннюю сторед процедуру SQL server, которас и делает что надо - закрывает транзакции, обнуляет счетчики и т.д.
3. Если используется провайдер MSDASQL (а он- провайдер по умолчанию) - ничего такого не происходит (и в целом - понятно почему) и коннект передается в пуле со всем мусором, который сподобится туда попасть.
4.Милая часть заключается в том, что в целом SQLOLEDB хуже совместим с SQL server и имеет issues которых не имеет MSDASQL - в частности, при select из темп таблиц надо ставить сначала set nocount on - или буде плохо (ADO 2.6 по крайней мере).
Также, если в коннект стринг явно казан провайдер его уже нельзя поменять в свойствах объекта connection - например если нужен MsDataShape - надо делать новую коннект стринг.

Наконец самая милая часть - то, что я тут написал, вы скорее всего больше нигде не найдете. Нигде в интернет или боже упаси на MS сайте этой простой информации в ясном виде мне найти не удалось.
Так что по десятке с вас, бездельники :lol: :lol: :lol:
Seryi
Ник закрыт как дубликат.
Posts: 6238
Joined: 14 Mar 2001 10:01
Location: .MD -> .SI -> .SE -> .AR.US -> .MD

Post by Seryi »

по десятке это точно :)
Я от MSDASQL отказался еще года 2 назад, когда провел пару тестов и выяснил что SQLOLEDB процентов на 8-10 быстрее работает.
А про ноукаунт он, это мы знаем.

Return to “Вопросы и новости IT”