Transactions Sql Server事务/隔离级别和锁定

Transactions Sql Server事务/隔离级别和锁定,transactions,sql-server-2008-r2,Transactions,Sql Server 2008 R2,我有一个SQL Server存储过程可以更新10个表,另一个存储过程只更新这10个表中的一个。让我们分别称它们为sp_updateAll和sp_updateSingle。 例如,sp_updateAll的伪代码是: Create Stored Procedure sp_updateAll Begin Begin TRAN UPDATE TABLE1 SET COLUMN = ‘VALUE’ UPDATE TABLE2

我有一个SQL Server存储过程可以更新10个表,另一个存储过程只更新这10个表中的一个。让我们分别称它们为sp_updateAll和sp_updateSingle。 例如,sp_updateAll的伪代码是:

Create Stored Procedure sp_updateAll
Begin
    Begin TRAN
        UPDATE TABLE1 
        SET COLUMN = ‘VALUE’

        UPDATE TABLE2 
        SET COLUMN = ‘VALUE’
        …
        UPDATE TABLE6 
        SET COLUMN = ‘VALUE’
        …
        UPDATE TABLE10 
        SET COLUMN = ‘VALUE’
  COMMIT TRAN
End 
sp_UpdateSingle的伪代码如下:
//这更新了表6,例如,实际上它可以是10个表中的任何一个

Create Stored Procedure sp_updateSingle
Begin
    Begin TRAN
    IF sp_UpdateAll is in progress, return an error.
    UPDATE TABLE6 
    SET COLUMN = ‘VALUE’
    COMMIT TRAN
END
我想确保一旦sp_updateAll开始执行,sp_updateSingle将返回一个错误。换句话说,在执行sp_UpdateAll时,不应允许对单个表进行更新。 有没有办法使用隔离级别/锁定提示来实现这一点?即使我们将隔离级别设置为Serializable,sp_UpdateSingle也有可能与sp_UpdateAll一起执行。例如,如果两个事务同时运行,则可能出现以下情况:

  • Tran1开始执行sp_UpdateAll。Tran2开始执行sp_UpdateSingle
  • 在到达更新表6之前切换Tran1。因此表6没有被Tran1锁定
  • Tran2执行并提交
  • Tran1继续执行
  • 这可能吗?如果是这样,那么什么是避免这种情况的好方法?我们是否需要一个额外的表来维护Tran1已经开始执行(类似于InUse指示符)?那么这个表应该是在sp_UpdateAll中更新的第一个表;我们设置指示器,并在sp_UpdateAll完成时将其清除。sp_UpdateSIngle在执行更新之前检查此指示器。 请帮助说明在这种情况下什么方法是好的

    感谢和问候

    Vikas

    如果我理解正确的话,我认为事务隔离级别不是问题的答案

    “我要确保一旦sp_updateAll开始执行,sp_updateSingle将返回一个错误。换句话说,在sp_updateAll执行时,不允许对单个表进行更新。”

    • 我认为您可以创建一个全局临时(虚拟)表,比如在第一个事务开始时执行的##sp1,并在事务完成时删除这个临时表
    • 在第二个事务中,您可以检查该表是否存在于while循环中(可能有延迟),并仅在该表不存在时运行事务

    如果我理解正确,我认为事务隔离级别不是答案

    “我要确保一旦sp_updateAll开始执行,sp_updateSingle将返回一个错误。换句话说,在sp_updateAll执行时,不允许对单个表进行更新。”

    • 我认为您可以创建一个全局临时(虚拟)表,比如在第一个事务开始时执行的##sp1,并在事务完成时删除这个临时表
    • 在第二个事务中,您可以检查该表是否存在于while循环中(可能有延迟),并仅在该表不存在时运行事务
    参见