【问题标题】:SQL Server - How to lock a table until a stored procedure finishesSQL Server - 如何在存储过程完成之前锁定表
【发布时间】:2011-04-09 10:21:54
【问题描述】:

我想这样做:

create procedure A as
  lock table a
  -- do some stuff unrelated to a to prepare to update a
  -- update a
  unlock table a
  return table b

这样的事情可能吗?

最终我希望我的 SQL Server 报告服务报告调用过程 A,然后仅在过程完成后显示表 a。 (我无法将过程 A 更改为返回表 a)。

【问题讨论】:

  • 您是否考虑过使用 SET TRANSACTION / COMMIT 。我不太确定你想在这里实现什么?
  • Xin 的回答更加简洁,占用的资源更少。不过我不得不使用 TABLOCKX。

标签: sql sql-server tsql stored-procedures locking


【解决方案1】:

为您的事务使用 TABLOCKX 锁定提示。 See this article 了解更多关于锁定的信息。

【讨论】:

  • 如果您在使用表格时其他人可以阅读表格,您也可以使用 UPDLOCK。
  • 交易从哪里来?我应该将我的整个 SP 包装在一个事务中吗?
  • 对于许多 SP 来说,从头开始事务并在最后提交它是有意义的。当然,这条规则也有例外,但总的来说,我认为这是一种很好的做法。
【解决方案2】:

我自己和link provided by David Moye 需要这个答案,决定这样做并认为它可能对其他有相同问题的人有用:

CREATE PROCEDURE ...
AS
BEGIN
  BEGIN TRANSACTION

  -- lock table "a" till end of transaction
  SELECT ...
  FROM a
  WITH (TABLOCK, HOLDLOCK)
  WHERE ...

  -- do some other stuff (including inserting/updating table "a")



  -- release lock
  COMMIT TRANSACTION
END

【讨论】:

  • 我们不能为此使用 sp_getapplock
  • 从文档 (msdn.microsoft.com/en-us/library/ms189823.aspx) 看来, sp_getapplock 也可以使用 sp_releaseapplock 来释放锁。还具有看起来不需要在事务中的优点。
  • TABLOCK 会阻止其他会话的更新,TABLOCKX 会阻止更新和读取。
  • 另外,如果需要,您可以将 lock-select 插入到表变量中以将其从输出中隐藏:DECLARE @HideSelectFromOutput TABLE ( DoNotOutput INT); INSERT INTO @HideSelectFromOutput SELECT TOP 1 Id FROM a WITH (TABLOCK, HOLDLOCK);
  • 在这个解决方案中,不是只有在运行一个select语句时才使用锁吗?
【解决方案3】:
BEGIN TRANSACTION

select top 1 *
from table1
with (tablock, holdlock)

-- You do lots of things here

COMMIT

这将保持“表锁”直到您当前的“交易”结束。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-24
    相关资源
    最近更新 更多