我写了一些代码来升级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
在运行此代码之前,我会给用户一个选择退出的机会。但是,我希望用户能够看到数据库的活动连接列表 - 这样他们就可以做出明智的决定。这让我想到了这个问题。
答案 0 :(得分:2)
主要是,DB锁只是为了表明它正在使用中。与代码/表对象相比,数据库实际上没有很多独占锁定情况。
单用户模式不是锁,而是允许的连接数。
我将ALTER DATABASE包装在TRY / CATCH块中,因为无法保证状态不会在check和ALTER DB之间发生变化。
但是,我可能错了或误解了这个问题......所以你还必须在上面的查询中测试数据库资源上的独占锁模式。上面的代码会显示任何锁,可能是在SSMS中打开空白查询窗口的人......
根据评论进行编辑
您可以通过以下方式检测谁正在使用它:
sys.dm_exec_connection
s sys.dm_exec_sessions
sys.dm_exec_requests
说实话,很难停止自动统计更新或用户进行单一连接。通常情况下,你这样就断开了所有其他用户的连接,而不是在等待......
ALTER DATABASE MYDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE
答案 1 :(得分:0)
如果数据库从您确定未使用的数据库变为忙碌,直到您尝试获取独占锁定为止,该怎么办?