2009-04-13 75 views
1

我写过一些代码来升级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个或多个返回行,则数据库必须是在使用中。这是真的?还是不是那么简单?

UPDATE以@ GBN的意见考虑在内,我已经决定要强制使用下面的语句现有连接的回滚:

ALTER DATABASE Test SET SINGLE_USER WITH ROLLBACK IMMEDIATE 

运行此代码之前,我给用户一个机会退出。但是,我希望用户能够看到数据库的活动连接列表 - 因此他们可以做出明智的决定。这导致我回到这个问题上。

回答

2

DB锁主要是为了显示它正在使用。与代码/表对象相比,数据库并没有真正的独占锁。

单用户模式不是锁,而是允许的连接数。

我会将ALTER DATABASE包装在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

在这种情况下,我想要做的是确定我是否可以将数据库减少到一个连接。有没有办法查询当前的连接集? – Mitkins 2009-04-13 22:51:47

0

如果数据库在您确定它没有被使用之前变得繁忙,直到您尝试获取排他锁的时候该怎么办?

+0

当然,没有什么可以阻止这种情况的发生。但是,升级过程的一部分是让用户消除与数据库的连接。所以希望数据库不会很忙。 – Mitkins 2009-04-13 22:46:22