Sid*_*awy 8 sql-server locking sql-server-2014
我有一个 SQL Server 2014 的生产实例,我需要对其进行一些轻度维护。
本质上,我需要在单个事务中替换两个整个表的内容。我想防止任何人在数据更改正在进行时查询任一表。桌子很小,我希望操作不到几秒钟。
不幸的是,我没有为此安排停机时间的好处。
所以问题是如何一次锁定多个对象 - 甚至整个数据库?
理想情况下,我可以简单地获取数据库级锁,进行更改,然后释放锁,但这在 SQL Server 2014 中似乎是不可能的。
Aar*_*and 12
您可以首先使用带有 UPDLOCK 的查询,以保护您免受整个事务中的任何事情的影响(脏读除外)。
它永远不可能是单个锁,因为单个锁不能跨越对象。但我仍然相信这可以完成你所追求的,只要你没有对 NOLOCK 的查询(如果你这样做了,你就会得到你所要求的!)。
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;
Run Code Online (Sandbox Code Playgroud)
使用 NOLOCK,用户可能会潜入中间并从两个表中进行查询,并在更新后从第一个表和更新前的第二个表中获取数据。但同样,这就是您允许 NOLOCK 时得到的结果。
而且也有可能在某个时候,处于默认隔离级别的用户可以查询bar
并查看旧值,但他们会阻止foo
.
我会不情愿地加入锁定潮流。
是你想实际锁定数据库为您的更新,为您的标题说,你可以把数据库在单用户模式和放心,只有您的连接可以连接在所有的,而你所做的更新:
ALTER DATABASE AdventureWorks2012
SET SINGLE_USER
GO
Run Code Online (Sandbox Code Playgroud)
在您更新之后:
ALTER DATABASE whatever
SET MULTI_USER
GO
Run Code Online (Sandbox Code Playgroud)
但是请注意,这可能很棘手 - 例如,SSMS 经常打开许多连接,因此在这些模式下它会开始表现不佳。最好的办法是在这种模式下使用 sqlcmd。
归档时间: |
|
查看次数: |
6043 次 |
最近记录: |