跨负载平衡应用程序的并发和锁定

时间:2019-08-12 14:48:44

标签: c# asp.net sql-server concurrency locking

我正在编写一个应用程序,用户可以在其中创建带有开始日期和结束日期的项目,并将它们保存到Microsoft Sql Server中托管的SQL数据库中。应用程序中的规则是,在给定的时间内,只有一个项目可以处于活动状态(没有重叠的项目)。该应用程序还需要进行负载平衡,这(据我所知)意味着传统的信号灯/锁定将不起作用。

一些其他项目:

  • 记录被保存到两个表中(基于业务需求)。
  • 允许用户在现有记录的中间“插入”记录。插入的记录可调整任何现有记录的开始和结束日期,以防止项目重叠(如有必要)。
  • 最理想的情况是,我们希望使用我们的ORM和.Net完成此任务。我们没有太多的余地来更改数据库架构,但是我们可以通过ORM创建事务并执行其他类型的SQL操作。

我们的目标是防止发生以下情况:

  • 来自多个用户的保存导致两个表中的项重叠(例如,用户1和2查询数据库,看到没有重叠的记录,并同时保存)
  • 从多个用户中进行保存,导致每个目标表中的状态不同(例如,两个用户“插入”记录,并且该操作在两个表之间进行交错。表A看起来用户1首先出现,表1 B看起来好像用户2排名第一。)

我的问题是,如何在负载平衡的服务器上同时锁定或阻止多个用户同时保存/插入。

注意:我们目前正在研究使用sp_getapplock,因为它似乎可以满足我们的要求,如果您对此有经验,或者觉得这将是一个错误的决定,并且希望对此进行详细说明!

编辑:添加了其他信息

1 个答案:

答案 0 :(得分:0)

至少有两个选择:

  • 您可以创建一个存储过程,该存储过程将INSERT操作包装在事务中:

    begin tran
        select to see if there is an existing record
        you can:
            - invalidate the previous record
            - insert a new record
        or
            - raise an error
        commit tran
    catch error
        rollback tran
    
  • 您可以采用“后赢制”策略,在这种策略中,您不使用写级别锁,而是使用读取级别的伪锁,本质上会忽略除最新记录以外的所有记录。