我有一个从视图中填充的大表。这样做是因为视图需要很长时间才能运行,并且更容易在表中提供数据。每隔一段时间就会运行一个更新表的过程。
TRUNCATE TABLE LargeTable
INSERT INTO LargeTable
SELECT *
FROM viewLargeView
WITH (HOLDLOCK)
我想在插入时锁定这个表,所以如果有人试图选择一个他们在截断后不会收到的记录。我正在使用的锁似乎锁定视图而不是表。
有没有更好的方法来解决这个问题?
答案 0 :(得分:6)
BEGIN TRY
BEGIN TRANSACTION t_Transaction
TRUNCATE TABLE LargeTable
INSERT INTO LargeTable
SELECT *
FROM viewLargeView
WITH (HOLDLOCK)
COMMIT TRANSACTION t_Transaction
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION t_Transaction
END CATCH
答案 1 :(得分:4)
确实,正确的锁定提示会影响源视图。
要使它在插入时没有人可以从表中读取:
insert into LargeTable with (tablockx)
...
在插入完成之前,您无需执行任何操作即可使表显示为空。插入始终在事务中运行,除非明确指定with (nolock)
或set transaction isolation level read uncommitted
,否则其他任何进程都无法读取未提交的行。据我所知,没有办法保护它。