SQL server 2016 - отваливается SINGLE USER(OLE DB)
От: blonduser  
Дата: 17.05.17 13:43
Оценка:
Всем доброго времени суток!

Модуль для работы с БД написан на С++ и работает с сервером через OLE DB.

Создаю подключение к БД.
Перед исправлением структуры БД перевожу её в SINGLE_USER MODE.
Исправляю структуру и возвращаю её в MULTI_USER MODE.

При этом другие модули пытаются писать в БД.

Но иногда происходит что-то непонятное.
Когда находимся в SINGLE_USER MODE пропадает доступ к базе.
Выдается сообщение об ошибки что уже одно подключение существует.

Проверял в пошаговом режиме. В момент исправления никому не удается подключится.
А вот под нагрузкой случается.

Кто нить сталкивался с подобным и как удалось побороть?


Спасибо.
Re: SQL server 2016 - отваливается SINGLE USER(OLE DB)
От: BlackEric http://black-eric.lj.ru
Дата: 17.05.17 14:17
Оценка:
Здравствуйте, blonduser, Вы писали:

B>Создаю подключение к БД.

B>Перед исправлением структуры БД перевожу её в SINGLE_USER MODE.
B>Исправляю структуру и возвращаю её в MULTI_USER MODE.

А что вы такого правите, что вам нужен SINGLE_USER MODE?
Решением будет отключить остальные модули, т.к. в SINGLE_USER MODE они наврядли смогут корректно отрабоать
https://github.com/BlackEric001
Re: SQL server 2016 - отваливается SINGLE USER(OLE DB)
От: Olaf Россия  
Дата: 17.05.17 18:51
Оценка:
Здравствуйте, blonduser, Вы писали:

B>Но иногда происходит что-то непонятное.

B>Когда находимся в SINGLE_USER MODE пропадает доступ к базе.
B>Выдается сообщение об ошибки что уже одно подключение существует.

Так может быть кто-то уже подключился и использует БД. Либо уже отключился, но не закрыл соединение. А вы пробовали смотреть подключения на сервере в этот момент (sp_who2 или select * from sys.dm_exec_sessions where is_user_process = 1 и т.п.)?
Re: SQL server 2016 - отваливается SINGLE USER(OLE DB)
От: rm822 Россия  
Дата: 18.05.17 17:38
Оценка:
B>Перед исправлением структуры БД перевожу её в SINGLE_USER MODE.
B>Исправляю структуру и возвращаю её в MULTI_USER MODE.
Это во первых опасный ход, потому как при потере коннекта она останется в single user
а во вторых — эта хрень несовместима с азурой, миррорингом, требует кучу прав, говнокод по современным меркам короче.

B>Кто нить сталкивался с подобным и как удалось побороть?

Ну да, есть 2 варианта которые работают по моему опыту
а) грубо говоря рисуешь мутекс через sp_getapplock, и все приложения должны работать через него.
б) тупо убиваешь перед апдейтом все соединения, открываешь транзакцию и начинаешь модифицировать схему базы.
В начале можно залочить все тупо прогнав EXECUTE sp_MSforeachtable 'select top 1 1 from [?] with(tablockx)';
Если не повезет — ну отвалится транзакция с роллбэком и все. Будет попытка номер два значит
Re[2]: SQL server 2016 - отваливается SINGLE USER(OLE DB)
От: blonduser  
Дата: 22.05.17 09:43
Оценка:
Здравствуйте, rm822, Вы писали:

B>>Перед исправлением структуры БД перевожу её в SINGLE_USER MODE.

B>>Исправляю структуру и возвращаю её в MULTI_USER MODE.
R>Это во первых опасный ход, потому как при потере коннекта она останется в single user
Кто первый подключился, тот и выводит БД в MULTI_USER.

R>а во вторых — эта хрень несовместима с азурой, миррорингом, требует кучу прав, говнокод по современным меркам короче.

Согласен с вами. Но кто платит тот и "заказывает музыку".
Если бы было можно, то обошлись бы без SINGLE_USER.

Есть множество приложений запущенных на разных станциях,
которые собирают данные и сами пишут в БД напрямую с использованием хранимых процедур.
Переделывать эти приложения никто не собирается.
Есть приложение которое контролирует структуру БД и оно никак не контролирует те приложения которые пишут.
Единственный способ запретить всем писать кроме одного это перевод в SINGLE_USER.

И вот этот SINGLE_USER отваливается под нагрузкой.
В отладчике все работает корректно.

Медитирую над трассами.
Re: SQL server 2016 - отваливается SINGLE USER(OLE DB)
От: blonduser  
Дата: 24.05.17 09:21
Оценка:
"Помедитировал" я над трассами и заметил один момент.
Для получения тела процедур и функций я использую sp_helptext.

Так вот доступ пропадает, когда между вызовом следующей команда после sp_helptext
проходит мало времени — единицы миллисекунд.

Затем несколько команд выполняются, а потом опять нет доступа.

Посмотрел процедуру sp_helptext.

Завершается функция следующим набором команд:
...

/* выдача результата */
select Text from #CommentText order by LineId

CLOSE  ms_crs_syscom
DEALLOCATE     ms_crs_syscom

DROP TABLE     #CommentText

return (0) -- sp_helptext


После получения результата я начинаю выполнять следующую команду.
А в этот момент происходит удаление курсора и таблицы.

Может это влиять, на то что следующей команде отказано в доступе?
И как с помощью OLE DB узнать что предыдущая команда завершила своё выполнение полностью?

Спасибо.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.