在尝试专用锁之前进行测试

时间:2009-04-13 15:04:25

标签: sql-server

我写了一些代码来升级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 个答案:

答案 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)

如果数据库从您确定未使用的数据库变为忙碌,直到您尝试获取独占锁定为止,该怎么办?