首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >数据库级锁

数据库级锁
EN

Database Administration用户
提问于 2017-11-29 20:41:27
回答 2查看 6.7K关注 0票数 8

我有一个SQL Server 2014的生产实例,需要对其进行一些简单的维护。

本质上,我需要在一个事务中替换两个整个表的内容。我希望在数据更改过程中防止任何人查询任何一个表。这些表都很小,我预计操作时间不会超过几秒钟。

不幸的是,我没有为这个计划停机的好处。

因此,问题是我如何能够同时锁定多个对象-甚至整个数据库?

理想情况下,我只需使用数据库级别的锁,进行更改,并释放锁,但在Server 2014中,这似乎是不可能的。

EN

回答 2

Database Administration用户

回答已采纳

发布于 2017-11-29 21:04:29

您可以首先使用UPDLOCK查询,以保护您不受整个事务的影响(除了脏读取之外)。

它不可能是一个锁,因为一个锁不能跨越对象。但我仍然相信,只要您没有对NOLOCK进行查询(如果您这样做了,您就得到了所要求的东西!),这就实现了您的目标。

代码语言:javascript
复制
BEGIN TRANSACTION;

SELECT pkcol FROM dbo.foo WITH (UPDLOCK, HOLDLOCK)
UNION ALL
SELECT pkcol FROM dbo.bar WITH (UPDLOCK, HOLDLOCK);

-- do other stuff

UPDATE dbo.foo SET ...;
UPDATE dbo.bar SET ...;

-- do other stuff

-- default isolation level users will be blocked until:
COMMIT TRANSACTION;

使用NOLOCK,用户可能潜入其中,从两个表中进行查询,并在更新后从第一个表中获取数据,在更新之前从第二个表中获取数据。但是,当你允许NOLOCK的时候,这也是你得到的。

而且,在这种情况下,处于默认隔离级别的用户可能会查询bar并查看旧值,但他们会阻止foo

票数 12
EN

Database Administration用户

发布于 2017-11-29 21:19:47

我会勉强赶上锁具的潮流。

如果您真的想为更新而锁定数据库,正如标题所述,您可以将数据库放在单用户模式中,并确保在进行更新时只有连接可以连接:

代码语言:javascript
复制
ALTER DATABASE AdventureWorks2012
SET SINGLE_USER
GO

在你更新之后:

代码语言:javascript
复制
ALTER DATABASE whatever
SET MULTI_USER
GO

但是,请注意,这可能很棘手--例如,SSMS通常会打开许多连接,因此在这种模式下会开始表现不佳。您最好的选择是在这种模式下使用sqlcmd。

票数 5
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/192013

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档