关于sql server:由多个用户编辑数据库记录

关于sql server:由多个用户编辑数据库记录

Editing database records by multiple users

我已经设计了数据库表(在MS SQL服务器上已规范化),并为应用程序创建了一个独立的Windows前端,少数用户将使用该窗口来添加和编辑信息。我们将添加一个网络界面,以便以后在整个生产区域进行搜索。

我担心如果两个用户开始编辑同一记录,那么最后提交更新的用户将是"赢家",并且重要的信息可能会丢失。我想到了许多解决方案,但是我不确定是否会造成更大的麻烦。

  • 不执行任何操作,并希望两个用户永远不会同时编辑同一条记录。 -可能永远不会被遮挡,但是如果会呢?
  • 编辑例程可以存储原始数据的副本以及更新,然后在用户完成编辑后进行比较。如果它们不同,请显示用户并确认更新-将需要存储两个数据副本。
  • 添加最后更新的DATETIME列,并在我们更新时检查它是否匹配,否则请显示差异。 -在每个相关表中都需要新列。
  • 创建一个编辑表,该表在用户开始编辑将要检查的记录时进行注册,并防止其他用户编辑同一记录。 -需要认真考虑程序流程,以防止死锁和记录在用户退出程序时被锁定。
  • 有没有更好的解决方案,或者我应该选择其中一种?


    如果您希望不经常发生冲突,那么乐观并发可能是您最好的选择。

    Scott Mitchell撰写了有关实现该模式的综合教程:
    实现乐观并发


    经典方法如下:

    • 向每个表添加一个"锁定"的布尔字段。
    • 默认情况下将其设置为false。
    • 用户开始编辑时,请执行以下操作:

      • 锁定行(如果无法锁定行,则锁定整个表)
      • 检查您要编辑的行上的标志
      • 如果标志为真,则

        • 通知用户他们目前无法编辑该行
      • 其他

        • 将标志设置为true
      • 释放锁

      • 保存记录时,将标志设置回false


    -first创建字段(更新时间)以存储最新更新记录
    -当任何用户选择记录保存选择时间时,
    比较选择时间和更新时间字段是否(更新时间)>(选择时间),这意味着另一个用户在选择记录后更新此记录


    SELECT FOR UPDATE和等效项很不错,只要您在微观时间内保持该锁定,但是对于宏观而言(例如,用户已加载数据且未按"保存",则应如上所述使用开放式并发。)我一直认为自己的名字是错误的-比"最后一位作家获胜"更为悲观,后者通常是唯一考虑的其他选择。)


    另一个选择是测试要更改的记录中的值是否与开始时的值相同:

    1
    2
    3
    4
    5
    SELECT
        customer_nm,
        customer_nm AS customer_nm_orig
    FROM demo_customer
    WHERE customer_id = @p_customer_id

    (显示customer_nm字段,用户进行更改)

    1
    2
    3
    4
    5
    6
    7
    UPDATE demo_customer
    SET customer_nm = @p_customer_name_new
    WHERE customer_id = @p_customer_id
    AND customer_name = @p_customer_nm_old

    IF @@ROWCOUNT = 0
        RAISERROR( 'Update failed: Data changed' );

    您不必在表中添加新列(并保持其最新状态),但是您必须创建更多详细的SQL语句并将新字段和旧字段传递给存储过程。

    它还具有您不锁定记录的优点-因为我们都知道,当不应该使用记录时,记录最终将保持锁定状态。


    @ Mark Harrison:SQL Server不支持该语法(SELECT ... FOR UPDATE)。

    SQL Server等效项是SELECT语句提示UPDLOCK

    有关更多信息,请参见SQL Server联机丛书。


    和我在一起,最好的方法是我有一个列lastupdate(时间戳数据类型)。
    选择和更新时只需比较此值
    该解决方案的另一个优势是,您可以使用此列来跟踪数据更改的时间。
    我认为如果只创建像isLock这样的支票来更新支票是不好的。


    数据库将为您执行此操作。看" select ... for update",它是专门为这种事情而设计的。它将为您提供对所选行的写锁定,然后您可以提交或回滚。


    推荐阅读