Модуль для работы с БД написан на С++ и работает с сервером через OLE DB.
Создаю подключение к БД.
Перед исправлением структуры БД перевожу её в SINGLE_USER MODE.
Исправляю структуру и возвращаю её в MULTI_USER MODE.
При этом другие модули пытаются писать в БД.
Но иногда происходит что-то непонятное.
Когда находимся в SINGLE_USER MODE пропадает доступ к базе.
Выдается сообщение об ошибки что уже одно подключение существует.
Проверял в пошаговом режиме. В момент исправления никому не удается подключится.
А вот под нагрузкой случается.
Кто нить сталкивался с подобным и как удалось побороть?
Спасибо.
Re: SQL server 2016 - отваливается SINGLE USER(OLE DB)
Здравствуйте, blonduser, Вы писали:
B>Создаю подключение к БД. B>Перед исправлением структуры БД перевожу её в SINGLE_USER MODE. B>Исправляю структуру и возвращаю её в MULTI_USER MODE.
А что вы такого правите, что вам нужен SINGLE_USER MODE?
Решением будет отключить остальные модули, т.к. в SINGLE_USER MODE они наврядли смогут корректно отрабоать
Здравствуйте, 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)
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)
Здравствуйте, 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)
"Помедитировал" я над трассами и заметил один момент.
Для получения тела процедур и функций я использую 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 узнать что предыдущая команда завершила своё выполнение полностью?