Тест перед попыткой эксклюзивной блокировки - PullRequest
1 голос
/ 13 апреля 2009

Я написал некоторый код для обновления базы данных SQL Server. Перед обновлением базы данных я получаю эксклюзивную блокировку через:

ALTER DATABASE Test SET SINGLE_USER WITH NO_WAIT

Однако я хотел бы проверить базу данных, чтобы увидеть, возможна ли эксклюзивная блокировка до . Я запускаю приведенный выше код. Тест не должен быть идеальным на 100%, я просто хотел бы избежать возможности тайм-аута при попытке получить эксклюзивную блокировку.

Для этого я написал следующий код:

SELECT 
    *
FROM 
    sys.db_tran_locks 
WHERE 
    resource_database_id = DB_ID('Test') AND
    request_session_id <> @@SPID

Я предполагаю, что если возвращена 1 или более строк, то база данных должна использоваться. Это правда? Или это не так просто?

ОБНОВЛЕНИЕ Принимая во внимание комментарии @ gbn, я решил принудительно откатить существующие соединения, используя следующее утверждение:

ALTER DATABASE Test SET SINGLE_USER WITH ROLLBACK IMMEDIATE

Перед запуском этого кода я дам пользователю возможность отказаться. Однако я бы хотел, чтобы пользователь мог видеть список активных подключений к базе данных, чтобы он мог принять обоснованное решение. Что приводит меня к этому вопросу.

Ответы [ 2 ]

2 голосов
/ 13 апреля 2009

В основном блокировка БД предназначена только для того, чтобы показать, что она используется. Базы данных на самом деле не имеют много исключительных ситуаций блокировки по сравнению с объектами кода / таблицы.

Однопользовательский режим - это не блокировка, а количество разрешенных подключений.

Я бы обернул базу данных ALTER в блок TRY / CATCH, потому что нет никакой гарантии, что состояние не изменится между проверкой и ALTER DB.

Однако я могу ошибаться или неправильно понимать вопрос ... поэтому вам также придется проверить режим исключительной блокировки ресурса базы данных в приведенном выше запросе. Ваш код выше покажет вам любую блокировку, которая может быть кем-то с открытым окном запроса в SSMS ...

Редактировать, основываясь на комментарии

Вы можете определить, кто его использует, по:

  • sys.dm_exec_connection с
  • sys.dm_exec_sessions
  • sys.dm_exec_requests

Если честно, сложно остановить автоматическое обновление статистики или пользователь подключается к одному соединению. Как правило, вам нужно отключить всех остальных пользователей и не тратить время на ожидание ...

ALTER DATABASE MYDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE
0 голосов
/ 13 апреля 2009

Что если база данных станет занятой с того момента, как вы определили, что она не используется, до момента, когда вы попытаетесь получить эксклюзивную блокировку?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...