我想执行以下操作:
TRUNCATE TABLE Table1;
TRUNCATE TABLE Table2;
-- I do not want to allow possibly the viewing and definitely the modification
-- of Table1 or Table2 at this point, so that I can make changes to them atomically
-- possibly even regardless of the isolation level in other sessions (or this one).
-- So, I lock both tables. I want to remove any data that could have made its way into
-- the tables, due to the current isolation level, for example, and remove any rows.
-- Also, from this point on, I want the tables to be unviewable (all queries blocked)
-- and unmodifyable (all INSERTs, UPDATEs, DELETEs blocked)
DELETE FROM Table1 WITH(TABLOCKX, HOLDLOCK);
DELETE FROM Table2 WITH(TABLOCKX, HOLDLOCK);
-- This is a long running complex INSERT operation into Table1
INSERT INTO Table1... SELECT ...
-- This is a long running complex INSERT operation into Table2, based on the
-- data in Table1 and some other ancillary tables
INSERT INTO Table2... SELECT ... FROM Table1...
COMMIT;
我希望阻止对Table1
命令完成的点到Table2
}和TRUNCATE
的所有访问,直到完全构造它们并且使用COMMIT
。优选地,甚至来自使用READ_UNCOMMITTED隔离级别的客户端,甚至是那些执行NOLOCK
查询的客户端,如果可能的话。
任何建议都将受到赞赏。
答案 0 :(得分:3)
使用分区切换。尽管人们普遍认为,分区切换不要求对表进行分区。在临时表中准备新数据,快速切换并替换旧数据:
create table users (
id int identity(1,1) primary key,
name char(100));
go
insert into users (name)
values ('A'), ('B'), ('C'), ('D');
go
select * from users;
create table staging (
id int identity(1,1) primary key,
name char(100));
create table staging_empty (
id int identity(1,1) primary key,
name char(100));
go
insert into staging (name)
values ('Z'), ('Y'), ('X');
go
begin transaction;
alter table users switch partition 1 to staging_empty;
alter table staging switch partition 1 to users;
commit
go
select * from users;
go
请参阅Transferring Data Efficiently by Using Partition Switching。
答案 1 :(得分:0)
使用BEGIN TRANSACTION
。除非您愿意将数据库置于单用户模式,否则AFAIK不能使用READ_UNCOMMITTED或NO_LOCK来阻止客户端。通过该事务,我认为您不需要DELETE...
语句
我面前没有SQLEM,所以这可能不完美:
BEGIN TRANSACTION
TRUNCATE TABLE Table1;
TRUNCATE TABLE Table2;
ALTER DATABASE [Works] SET MULTI_USER WITH NO_WAIT
-- This is a long running complex INSERT operation into Table1
INSERT INTO Table1... SELECT ...
-- This is a long running complex INSERT operation into Table2, based on the
-- data in Table1
INSERT INTO Table2... SELECT ... FROM Table1...
ALTER DATABASE [Works] SET MULTI_USER WITH NO_WAIT
COMMIT;