SQL 2000 - чудеса с незакрывающейся транзакцией
-
- Уже с Приветом
- Posts: 12014
- Joined: 05 Apr 2000 09:01
- Location: Philadelphia, PA, USA
SQL 2000 - чудеса с незакрывающейся транзакцией
Возникла у нас проблемма с аппликатион. Путем включения всех возможных логов выяснено - проблемма происходит вследствии незакрытой транзакции.
Все хорошо, одна беда - не могу понять, почему транзакция не закрывается и как такое возможно.
Нашел я значит по логам место где оноа вроде создается. Происходит это в сторед процедуре, которая вызывается из другой сторед процедуры. Схема там простая:
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 не знаю - объект создается из дефолт.
Что кто может сказать мудрого?
Все хорошо, одна беда - не могу понять, почему транзакция не закрывается и как такое возможно.
Нашел я значит по логам место где оноа вроде создается. Происходит это в сторед процедуре, которая вызывается из другой сторед процедуры. Схема там простая:
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 не знаю - объект создается из дефолт.
Что кто может сказать мудрого?
-
- Уже с Приветом
- Posts: 28294
- Joined: 29 Aug 2000 09:01
- Location: SPB --> Gloucester, MA, US --> SPB --> Paris
-
- Уже с Приветом
- Posts: 12014
- Joined: 05 Apr 2000 09:01
- Location: Philadelphia, PA, USA
Dmitry67 wrote:В 6.5 были проблемы
У нас даже висел процесс которые мертвые транзакции убивал
За 2000 такого поведения не видел
А у вас connection pool есть ?
Нету. Для каждой команды коннекшин создается заново. Правда все это делается в COM+ но я и так соображал и эдак - не вижу как коннетион может быть реюз.
Интуиция мне подсказывает - что то с ADO - но далше она не говорит
Да, еще что удивляет - что время жизни процессов частенько значительно больше 30 секунд таймоута. Отчего сие? Наскока понимаю новая коннекшин должна создавать новый процесс?
-
- Уже с Приветом
- Posts: 28294
- Joined: 29 Aug 2000 09:01
- Location: SPB --> Gloucester, MA, US --> SPB --> Paris
-
- Уже с Приветом
- Posts: 12014
- Joined: 05 Apr 2000 09:01
- Location: Philadelphia, PA, USA
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
-
- Уже с Приветом
- Posts: 12014
- Joined: 05 Apr 2000 09:01
- Location: Philadelphia, PA, USA
Упдате - вот как виглиаит видержка 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 сек) и защитал себе все трансактсии с самого начала - хотиа кажды рас откриваетсиа новая коннецтион и трансактсия в СП одна.
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 сек) и защитал себе все трансактсии с самого начала - хотиа кажды рас откриваетсиа новая коннецтион и трансактсия в СП одна.
-
- Уже с Приветом
- Posts: 28294
- Joined: 29 Aug 2000 09:01
- Location: SPB --> Gloucester, MA, US --> SPB --> Paris
-
- Новичок
- Posts: 30
- Joined: 09 Feb 2002 10:01
- Location: Kharkov, Ukraine
Нечто подобное обсуждалось на sql.ru
http://www.sql.ru/forum/actualthread.aspx?bid=1&tid=40063&pg=-1
http://www.sql.ru/forum/actualthread.aspx?bid=1&tid=40063&pg=-1
-
- Уже с Приветом
- Posts: 12014
- Joined: 05 Apr 2000 09:01
- Location: Philadelphia, PA, USA
Dmitry67 wrote:Сохранение нового @@spid совершенно нормально
Я видел что у Вас open_tran=0
Почему Вы считаете что locks Идут от этой транзакции ?
Не там open_tran=10, нолик это другая колонка.
Да вроде разобрался более - менее. Родимое ADO, конечно. Оно делает коннектион пулинг. Ну так как коннект не закрывается - то сервер и не освобождает ресурсы - ни транзакции, ни локи. Все это навешивается на следующий колл. И так далее.
Щас пытаюсь понять, кто же, собственно делает этот пулинг -IIS или OLE DB Provider и как избавиться. Коннектион оъект создается там как CreateObject() из COM+ сомпонента, а тот вызывается с ASP страници.
Причем если создавать коннект на самой странице и там юзать, то даже
conn.close
set conn = Nothing
воспринимается не более чем шутка а не руководство к действию.
-
- Ник закрыт как дубликат.
- Posts: 6238
- Joined: 14 Mar 2001 10:01
- Location: .MD -> .SI -> .SE -> .AR.US -> .MD
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
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
-
- Уже с Приветом
- Posts: 12014
- Joined: 05 Apr 2000 09:01
- Location: Philadelphia, PA, USA
Seryi wrote:ключевое слово OLE DB Services=-2
Да, спасибо, это работает прекрасно. Хотя ресурся сразу и не освобождаются, но процесс уже не реюзается и снежного кома навешивания на него ресурсов не происходит.
Все бы прекрасно, но при этом отказывается работать msDataShape. А мы его юзаем. Вякает сразу (еще при открытии коннекта) что мултипле степ OLE DB операция привела к шибко печальным последствиям.
Черт возьми. Ну так же не бывает. Один из нас идиот - или я, или Microsoft.
Не может же это так работать штатно. Почему когда я закрываю коннект из VB программы - ресурсы освобождаются сей момент как закрывается коннект, а то же самое из COM+ компонента, вызываемого с ASP страници - тока минуты через полторы в луцшем случае. В чем дело? И как заставить скотину закрывать все сразу? Не может же быть, чтобы я первый на это набрел - архитекрура - то классическая.
Может тут какие сетевые проблеммы? Как вообще физически поддерживается коннект и что происходит, когда закрывается?
-
- Уже с Приветом
- Posts: 1935
- Joined: 15 Sep 2003 17:49
- Location: Ukraine, Mariupol -> USA everywhere :-)
А компонент у вас не пулится часом? Может референс где-то остается.
У COM+ свои таймауты.
Нужно позвать мeтоды контекста или что там у вас используется, это принудит COM+ разрушить или поместить компонент в пул. Если пулится, то нужно это правильно реализовать. IObjectControl насколько я припоминаю.
У COM+ свои таймауты.
Нужно позвать мeтоды контекста или что там у вас используется, это принудит COM+ разрушить или поместить компонент в пул. Если пулится, то нужно это правильно реализовать. IObjectControl насколько я припоминаю.
-
- Уже с Приветом
- Posts: 12014
- Joined: 05 Apr 2000 09:01
- Location: Philadelphia, PA, USA
NNemo wrote:А компонент у вас не пулится часом? Может референс где-то остается.
У COM+ свои таймауты.
Нужно позвать мeтоды контекста или что там у вас используется, это принудит COM+ разрушить или поместить компонент в пул. Если пулится, то нужно это правильно реализовать. IObjectControl насколько я припоминаю.
Ну даже если компонент пулится, то я ведь в одном методе открываю коннект, шлю SQL, закрываю коннект и сет его носинг. Усе. Никаких референсов на уровне объекта - в сущности обычная функция. Почему эта скотина не желает закрыться, если я его явно закрываю и уничтожаю?
-
- Ник закрыт как дубликат.
- Posts: 6238
- Joined: 14 Mar 2001 10:01
- Location: .MD -> .SI -> .SE -> .AR.US -> .MD
vovap, вот подробная статья про Connection Pooling, почитайте возможно найдется ответ
http://msdn.microsoft.com/library/defau ... oling2.asp
http://msdn.microsoft.com/library/defau ... oling2.asp
-
- Уже с Приветом
- Posts: 12014
- Joined: 05 Apr 2000 09:01
- Location: Philadelphia, PA, USA
Seryi wrote:vovap, вот подробная статья про Connection Pooling, почитайте возможно найдется ответ
http://msdn.microsoft.com/library/defau ... oling2.asp
Спасибо, я это уже находил. Попробую еще посмотреть. Старая только - это еще про ADO 2.
Попробую поискать инфу по более глубокому механизму коннекта. Есть у меня подозрения к сетевому уровню.
-
- Уже с Приветом
- Posts: 1935
- Joined: 15 Sep 2003 17:49
- Location: Ukraine, Mariupol -> USA everywhere :-)
vovap wrote:NNemo wrote:А компонент у вас не пулится часом? Может референс где-то остается.
У COM+ свои таймауты.
Нужно позвать мeтоды контекста или что там у вас используется, это принудит COM+ разрушить или поместить компонент в пул. Если пулится, то нужно это правильно реализовать. IObjectControl насколько я припоминаю.
Ну даже если компонент пулится, то я ведь в одном методе открываю коннект, шлю SQL, закрываю коннект и сет его носинг. Усе. Никаких референсов на уровне объекта - в сущности обычная функция. Почему эта скотина не желает закрыться, если я его явно закрываю и уничтожаю?
А что из функции возвращается? Не рекордсет часом в другой слой?
Может он тоже референс на коннекцию держит? Они поди на одном сервере все живут... Кто его знает как там MS cсылки посчитал?
-
- Уже с Приветом
- Posts: 12014
- Joined: 05 Apr 2000 09:01
- Location: Philadelphia, PA, USA
-
- Уже с Приветом
- Posts: 12014
- Joined: 05 Apr 2000 09:01
- Location: Philadelphia, PA, USA
Да, так вот что удалось в конце концов выяснить.
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 сайте этой простой информации в ясном виде мне найти не удалось.
Так что по десятке с вас, бездельники
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 сайте этой простой информации в ясном виде мне найти не удалось.
Так что по десятке с вас, бездельники
-
- Ник закрыт как дубликат.
- Posts: 6238
- Joined: 14 Mar 2001 10:01
- Location: .MD -> .SI -> .SE -> .AR.US -> .MD