插入时锁定表格
我有一张从视图中填充的大表格。这样做是因为视图需要很长时间才能运行,并且数据很容易在表中使用。每隔一段时间运行一次程序以更新表格。插入时锁定表格
TRUNCATE TABLE LargeTable
INSERT INTO LargeTable
SELECT *
FROM viewLargeView
WITH (HOLDLOCK)
我想在插入时锁定此表,所以如果有人试图选择一条记录,截断后他们将不会收到任何记录。我正在使用的锁似乎锁定了视图而不是表格。
有没有更好的方法来解决这个问题?
BEGIN TRANSACTION t_Transaction
BEGIN TRY
TRUNCATE TABLE LargeTable
INSERT INTO LargeTable
SELECT *
FROM viewLargeView
WITH (HOLDLOCK)
COMMIT t_Transaction
END TRY
BEGIN CATCH
ROLLBACK t_Transaction
END CATCH
不要以为这会做任何事情。 “truncate”不受事务影响,即使没有指定一个,它本身也是一个事务。 – Andomar 2012-03-23 16:08:45
其实TRUNCATEs回滚有一些警告。见[this](http://blog.sqlauthority.com/2007/12/26/sql-server-truncate-cant-be-rolled-back-using-log-files-after-transaction-session-is-closed /) – 2013-08-16 15:47:00
确实,您正确的锁定提示会影响源视图。
为了让这个没有人可以从表中读取,当你插入:
insert into LargeTable with (tablockx)
...
你不必做任何事情来使表看空,直至插入完成后。插入始终在事务中运行,除非它们明确指定了with (nolock)
或set transaction isolation level read uncommitted
,否则其他进程不能读取未提交的行。就我所知,没有办法保护这一点。
在插入和关闭之后打开一个事务怎么样? – 2012-03-23 15:51:33
当打开一个事务时,另一个用户可以从表中选择? – JBone 2012-03-23 15:57:07
仅供参考,我建议您使用DELETE而不是TRUNCATE,因为TRUNCATE是DDL,而不是像DELETE这样的DML,因此需要更大的权限。另外,如果你在交易中(这是你的问题的正确答案)包装这些,他们将有效地执行相同的操作。 – RBarryYoung 2012-03-23 16:02:34