Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 MSSQL через ADO - пул соединений и чудеса с незавершенными транзакциями  [new]
fisher
Member

Откуда:
Сообщений: 60
Использую вложенные транзакции при работе через ADO следующим образом:
- открываю соединение
- посылаю BEGIN TRANSACTION (пробовал и через begintrans/committrans - тот же эффект)
- выполняются всякие разные изменения связанных данных в базе (в т.ч. через сложные хранимки, где могут быть свои транзакции)
- посылаю COMMIT TRANSACTION
Соединение явно не закрываю и в ряде случаев при отмене транзакции не посылаю ROLLBACK, предполагая что он сделается неявно (как и закрытие соединения) при выходе из контекста создавшего соединение (который происходит тут же) - т.е. при уничтожении переменной соединения

Но, как оказалось, не тут-то было. Выяснилось, что по дефолту ADO не уничтожает такие соединения а помещает в пул и переиспользует. В результате на практике наблюдается интересная картина - если транзакция осталась незавершенной, то дальше в этом соединении могут происходить чудеса, механику которых я затрудняюсь объяснить. Когда в новой транзакции (с точки зрения посылающей стороны) происходит фиксация предыдущей незавершенной транзакция и часть новой. И так далее. Сайд-эффекты зависят от поведения пула.
Теоретически я конечно могу пытаться всегда когда надо откатывать транзакции и закрывать соединение явно, но на практике я все равно не могу этого гарантировать, поэтому хотелось бы чтобы неявное закрытие соединения приводило к его уничтожению с откатом незавершенных транзакций (фиг с ним, с затратами на создание соединений, не смертельно).

Нашел, что отключить сервис пула ADO можно через реестр и в строке соединения, установив опцию OLE DB Services=-2
Пока прописал в строке соединения, сижу наблюдаю... В реестре боюсь установить не там где надо, так как не до конца понимаю для какого провайдера прописать (в строке соединения у меня просто driver={SQL Server} прописано).
В чем вопрос, собственно. Встречал еще рекомендации установить OLE DB Services=-4. Это типа кроме пула соединений ADO отключает еще и некий "Automatic Transaction Enlistment", по которому что-то не шибко гуглится.
Скажите пожалуйста, кто в курсе, как именно изменится поведение при его отключении.
Ну и буду рад любым комментариям, способным помочь разобраться с ситуацией.
26 окт 18, 11:06    [21715743]     Ответить | Цитировать Сообщить модератору
 Re: MSSQL через ADO - пул соединений и чудеса с незавершенными транзакциями  [new]
invm
Member

Откуда: Москва
Сообщений: 9345
Не нужно лениться писать ROLLBACK везде, где он нужен. И тогда описанных проблем не будет.
26 окт 18, 11:23    [21715769]     Ответить | Цитировать Сообщить модератору
 Re: MSSQL через ADO - пул соединений и чудеса с незавершенными транзакциями  [new]
fisher
Member

Откуда:
Сообщений: 60
invm
Не нужно лениться писать ROLLBACK везде, где он нужен. И тогда описанных проблем не будет.

Просто будет минимизирована вероятность появления описанных проблем.
Даже если роллбэк будет прописан абсолютно везде и будут корректно перехватываться все эксепшены приложения-инициатора, то все равно единственный краш приложения произошедший "не вовремя" приведет к зависанию и последующему переиспользованию соединения с незавершенной транзакцией и последующим недопустимым сайд-эффектам.
Пока что было бы интересно обсудить возможность своевременного и гарантированного закрытия соединений.
Насколько я понял, это не такая уж экзотика и "живые" люди используют отключение пула.
26 окт 18, 11:35    [21715793]     Ответить | Цитировать Сообщить модератору
 Re: MSSQL через ADO - пул соединений и чудеса с незавершенными транзакциями  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7754
fisher,

Вы выполняете сценарий "солнечного дня" и полагаетесь на неявное поведение функций. Во избежание проблем необходимо применять полный контроль над транзакциями и ошибками, в частности, в обработчике ошибок кода выполняться проверку счетчика транзакций открытого соединения и, если оно > 0, выполнять ROLLBACK.
26 окт 18, 11:36    [21715798]     Ответить | Цитировать Сообщить модератору
 Re: MSSQL через ADO - пул соединений и чудеса с незавершенными транзакциями  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7754
fisher,

Вы должны явно закрывать соединение при использовании пула.
26 окт 18, 11:39    [21715803]     Ответить | Цитировать Сообщить модератору
 Re: MSSQL через ADO - пул соединений и чудеса с незавершенными транзакциями  [new]
fisher
Member

Откуда:
Сообщений: 60
Владислав Колосов
fisher,
Вы выполняете сценарий "солнечного дня" и полагаетесь на неявное поведение функций. Во избежание проблем необходимо применять полный контроль над транзакциями и ошибками, в частности, в обработчике ошибок кода выполняться проверку счетчика транзакций открытого соединения и, если оно > 0, выполнять ROLLBACK.

Наборот. Я хочу чтобы при любом сценарии когда "что-то пошло не так", вплоть до краша приложения, незавершенная транзакция была гарантированно отменена.
26 окт 18, 11:39    [21715804]     Ответить | Цитировать Сообщить модератору
 Re: MSSQL через ADO - пул соединений и чудеса с незавершенными транзакциями  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7754
fisher,

при счетчике 0 открытых транзакций нет. При краше приложения пул будет уничтожен и транзакции откатит сервер.
26 окт 18, 11:40    [21715806]     Ответить | Цитировать Сообщить модератору
 Re: MSSQL через ADO - пул соединений и чудеса с незавершенными транзакциями  [new]
fisher
Member

Откуда:
Сообщений: 60
Владислав Колосов
fisher,
При краше приложения пул будет уничтожен и транзакции откатит сервер.

Этого не происходит. Пул держит не приложение. Это подсистема OLEDB.
26 окт 18, 11:42    [21715811]     Ответить | Цитировать Сообщить модератору
 Re: MSSQL через ADO - пул соединений и чудеса с незавершенными транзакциями  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7754
fisher,

чудеса пишете. У Вас отдельное приложение для связи с сервером? Как у Вас живет класс вне приложения?
26 окт 18, 11:46    [21715815]     Ответить | Цитировать Сообщить модератору
 Re: MSSQL через ADO - пул соединений и чудеса с незавершенными транзакциями  [new]
invm
Member

Откуда: Москва
Сообщений: 9345
fisher
Даже если роллбэк будет прописан абсолютно везде и будут корректно перехватываться все эксепшены приложения-инициатора, то все равно единственный краш приложения произошедший "не вовремя" приведет к зависанию и последующему переиспользованию соединения с незавершенной транзакцией
Вы фантазируете. Пул подключений работает на уровне приложения, а не системы.
26 окт 18, 11:50    [21715826]     Ответить | Цитировать Сообщить модератору
 Re: MSSQL через ADO - пул соединений и чудеса с незавершенными транзакциями  [new]
fisher
Member

Откуда:
Сообщений: 60
Владислав Колосов
fisher,
чудеса пишете. У Вас отдельное приложение для связи с сервером? Как у Вас живет класс вне приложения?

Эти чудеса, к сожалению, приходится наблюдать :)
COM-компоненты - это не совсем классы. Это довольно хитрые приложения, с которыми можно работать подобно классам.
26 окт 18, 11:51    [21715829]     Ответить | Цитировать Сообщить модератору
 Re: MSSQL через ADO - пул соединений и чудеса с незавершенными транзакциями  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7754
fisher,

почитайте, что такое COM объекты.
26 окт 18, 12:12    [21715869]     Ответить | Цитировать Сообщить модератору
 Re: MSSQL через ADO - пул соединений и чудеса с незавершенными транзакциями  [new]
fisher
Member

Откуда:
Сообщений: 60
Формулировки открытым текстом, что пул ADO не является частью приложения я не нашел, но здесь есть интересная формулировка:
автор
Connections are pooled per process, per application domain, per connection string and when integrated security is used, per Windows identity.

Если бы пул существовал только в рамках приложения, то к чему бы было это упоминать? Кстати, там же упоминается, что явное закрытие соединения (close) не уничтожает соединение, а гарантированно возвращает его в пул.
Аналогичное упоминание (про сепарацию соединений в пуле "per application") нахожу и в других источниках.
Нашел, кстати, старую ветку где чел безответно задавал похожие вопросы.
26 окт 18, 12:28    [21715906]     Ответить | Цитировать Сообщить модератору
 Re: MSSQL через ADO - пул соединений и чудеса с незавершенными транзакциями  [new]
invm
Member

Откуда: Москва
Сообщений: 9345
fisher,

Почитайте, что такое домен приложения.
26 окт 18, 12:40    [21715932]     Ответить | Цитировать Сообщить модератору
 Re: MSSQL через ADO - пул соединений и чудеса с незавершенными транзакциями  [new]
fisher
Member

Откуда:
Сообщений: 60
invm
fisher,
Почитайте, что такое домен приложения.

Почитал. И как это работает против моего предположения?
26 окт 18, 12:50    [21715960]     Ответить | Цитировать Сообщить модератору
 Re: MSSQL через ADO - пул соединений и чудеса с незавершенными транзакциями  [new]
invm
Member

Откуда: Москва
Сообщений: 9345
fisher
Почитал.
И вычитали, что домен приложения глобальная структура?
26 окт 18, 12:54    [21715969]     Ответить | Цитировать Сообщить модератору
 Re: MSSQL через ADO - пул соединений и чудеса с незавершенными транзакциями  [new]
fisher
Member

Откуда:
Сообщений: 60
Предлагаю пока прервать обсуждение. Обсуждаемый вопрос для меня важен, потому как я наблюдал поведение которое не могу объяснить иначе и хочу найти объяснение, так как чудес не бывает. Но этот вопрос подождет.
Гораздо важнее для меня прямо сейчас ответ на заданный ранее вопрос:
Что произойдет при указании OLE DB Services=-4? Как изменится поведение соединений? Что такое "Automatic Transaction Enlistment" в данном контексте?
26 окт 18, 13:05    [21715997]     Ответить | Цитировать Сообщить модератору
 Re: MSSQL через ADO - пул соединений и чудеса с незавершенными транзакциями  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31354
fisher
Кстати, там же упоминается, что явное закрытие соединения (close) не уничтожает соединение, а гарантированно возвращает его в пул.
При закрытии соединения, и возврате его в пул, транзакция гарантированно откатывается.

У вас, очевидно, проблема в том, что при крахе вашего приложения то, другое приложение, не выполняет Close.

fisher
Выяснилось, что по дефолту ADO не уничтожает такие соединения а помещает в пул и переиспользует. В результате на практике наблюдается интересная картина - если транзакция осталась незавершенной, то дальше в этом соединении могут происходить чудеса, механику которых я затрудняюсь объяснить. Когда в новой транзакции (с точки зрения посылающей стороны) происходит фиксация предыдущей незавершенной транзакция и часть новой. И так далее. Сайд-эффекты зависят от поведения пула.
Или вы путаете (используете неподходящщую терминологию), называя "пулом коннектов" такие ситуации, когда ADO оставляет открытые коннекты (т.е. не возвращает их в пул).

Но это, вообще говоря, проблема криворуких программистов, а не какого то неожидаемого поведения сиквела или компонентов доступа.

Либо вы никогда не допускаете ситуацию, когда ADO не возвращает коннекты в пул, либо вы контролируете состояние всех ваших открытых (взятых из пула, и не возвращённых в пул) коннектов, закрывая открытые транзакции
26 окт 18, 13:06    [21715999]     Ответить | Цитировать Сообщить модератору
 Re: MSSQL через ADO - пул соединений и чудеса с незавершенными транзакциями  [new]
aleks222
Member

Откуда:
Сообщений: 952
invm
Не нужно лениться писать ROLLBACK везде, где он нужен. И тогда описанных проблем не будет.

Не нужно лениться закрывать соединения.
Приложение ваще не должно пользоваться begin transaction.

fisher
единственный краш приложения произошедший "не вовремя" приведет к зависанию и последующему переиспользованию соединения с незавершенной транзакцией и последующим недопустимым сайд-эффектам.

Не надо фантазировать.

Но если фантазия неудержима - при открытии соединения проверяйте

if @@trancount > 0 rollback transaction;
26 окт 18, 13:15    [21716021]     Ответить | Цитировать Сообщить модератору
 Re: MSSQL через ADO - пул соединений и чудеса с незавершенными транзакциями  [new]
invm
Member

Откуда: Москва
Сообщений: 9345
fisher
Что произойдет при указании OLE DB Services=-4? Как изменится поведение соединений? Что такое "Automatic Transaction Enlistment" в данном контексте?
https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/ole-db-odbc-and-oracle-connection-pooling
Для вас никак не изменится - вы управляете транзакциями явно, а не средствами ADO.
26 окт 18, 13:50    [21716095]     Ответить | Цитировать Сообщить модератору
 Re: MSSQL через ADO - пул соединений и чудеса с незавершенными транзакциями  [new]
fisher
Member

Откуда:
Сообщений: 60
alexeyvg
fisher
Кстати, там же упоминается, что явное закрытие соединения (close) не уничтожает соединение, а гарантированно возвращает его в пул.
При закрытии соединения, и возврате его в пул, транзакция гарантированно откатывается.

У вас, очевидно, проблема в том, что при крахе вашего приложения то, другое приложение, не выполняет Close.

Возможно. Это было просто к слову, что даже при явном "закрытии" соединения оно на самом деле не закрывается при наличии пулинга.

alexeyvg
fisher
Выяснилось, что по дефолту ADO не уничтожает такие соединения а помещает в пул и переиспользует. В результате на практике наблюдается интересная картина - если транзакция осталась незавершенной, то дальше в этом соединении могут происходить чудеса, механику которых я затрудняюсь объяснить. Когда в новой транзакции (с точки зрения посылающей стороны) происходит фиксация предыдущей незавершенной транзакция и часть новой. И так далее. Сайд-эффекты зависят от поведения пула.
Или вы путаете (используете неподходящщую терминологию), называя "пулом коннектов" такие ситуации, когда ADO оставляет открытые коннекты (т.е. не возвращает их в пул).

Все возможно. Я уже мало что понимаю. Мой мозг взрывает не наличие соединений с незавершенными транзакциями, а возможность продолжения этих транзакций после повторного соединения, которое логика программы совершенно логично ожидает как "девственное" с точки зрения возможных сайд-эффектов. То есть их быть не должно. А они есть. Я своими глазами наблюдал при переподключении и отработке новых транзакций фиксацию транзакции, начатую полчаса назад. Полчаса, Карл!
26 окт 18, 15:20    [21716241]     Ответить | Цитировать Сообщить модератору
 Re: MSSQL через ADO - пул соединений и чудеса с незавершенными транзакциями  [new]
fisher
Member

Откуда:
Сообщений: 60
invm, Я застрял на попытке перевода и осознания фразы
Enlist - 'true'. When true, the pooler automatically enlists the connection in the current transaction context of the creation thread if a transaction context exists.
26 окт 18, 15:24    [21716252]     Ответить | Цитировать Сообщить модератору
 Re: MSSQL через ADO - пул соединений и чудеса с незавершенными транзакциями  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31354
fisher
Мой мозг взрывает не наличие соединений с незавершенными транзакциями, а возможность продолжения этих транзакций после повторного соединения, которое логика программы совершенно логично ожидает как "девственное" с точки зрения возможных сайд-эффектов. То есть их быть не должно. А они есть. Я своими глазами наблюдал при переподключении и отработке новых транзакций фиксацию транзакции, начатую полчаса назад. Полчаса, Карл!
Да не может такого быть, не может из пула взяться соединение с незакрытой транзакцией.

Это всё легко проверить, зачем чего то ловить, достаточно набросать тест.

Просто где то не делается Close
26 окт 18, 17:44    [21716452]     Ответить | Цитировать Сообщить модератору
 Re: MSSQL через ADO - пул соединений и чудеса с незавершенными транзакциями  [new]
Mind
Member

Откуда: Лучший город на Земле
Сообщений: 2322
alexeyvg
fisher
Мой мозг взрывает не наличие соединений с незавершенными транзакциями, а возможность продолжения этих транзакций после повторного соединения, которое логика программы совершенно логично ожидает как "девственное" с точки зрения возможных сайд-эффектов. То есть их быть не должно. А они есть. Я своими глазами наблюдал при переподключении и отработке новых транзакций фиксацию транзакции, начатую полчаса назад. Полчаса, Карл!
Да не может такого быть, не может из пула взяться соединение с незакрытой транзакцией.
Конечно не может. ТС написал кривой код и теперь грешит на пул.
автор
SQL Server provides a procedure sp_reset_connection that is designed to reset the settings and the state. So when you use connection pooling (the default), every time you open a connection, ADO.NET executes sp_reset_connection to make sure you get a "clean" connection before it hands it over to you.

Вы явно оставляете где-то открытые транзакции, которые висят по пол часа, а потом начинаете в них выполнять какие то команды.
А теперь еще объясните, если у вас каждый процесс открывает и закрывает транзакцию (ну или даже с учетом вложенных транзакций), то счетчик транзакций должен быть:
0
+1=1 -- BEGIN
+1=2 -- BEGIN
-1=1 -- COMMIT
-1=0 -- COMMIT
так?
Ну а если как вы утверждаете ваш процесс получает сессию с открытой транзакцией:
1
+1=2 -- BEGIN
+1=3 -- BEGIN
-1=2 -- COMMIT
-1=1 -- COMMIT
то кто простите делает "фиксацию транзакции, начатую полчаса назад"? Если у вас там идеальный код, то кто выполняет лишний COMMIT?

fisher
при отмене транзакции не посылаю ROLLBACK
А вот это конечно форменная глупость.
26 окт 18, 21:20    [21716600]     Ответить | Цитировать Сообщить модератору
 Re: MSSQL через ADO - пул соединений и чудеса с незавершенными транзакциями  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31354
Mind
fisher
при отмене транзакции не посылаю ROLLBACK
А вот это конечно форменная глупость.
Да в принципе можно и не посылать. Но тогда нужно быть уверенным, что выполняешь Close (возвращая коннект в пул, или реально его закрывая, это уже неважно, результат будет одинаковый).
26 окт 18, 22:47    [21716636]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить