sql server -多用户编辑数据库记录

Translate

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

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

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

有没有更好的解决方案,或者我应该选择其中一种?

This question and all comments follow the "Attribution Required."

所有的回答

Translate

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

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

来源
AJ.
Translate

经典方法如下:

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

    • 锁定行(如果无法锁定,则锁定整个表)
    • 检查您要编辑的行上的标志
    • if the flag is true then
      • 通知用户他们目前无法编辑该行
    • else
      • 将标志设置为true
    • 释放锁

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

来源
Julian Lee
Translate

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

来源
Translate

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

SQL Server的等效项是SELECT陈述提示UPDLOCK.

看到SQL Server联机丛书欲获得更多信息。

来源
Translate

-首先创建字段(更新时间)以存储最后的更新记录-当任何用户选择记录保存选择时间时,在选择时间和更新时间字段之间进行比较,如果(更新时间)>(选择时间)意味着另一位用户在选择之后更新了该记录记录

来源
Guy
Translate

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

SELECT 
    customer_nm,
    customer_nm AS customer_nm_orig
FROM demo_customer
WHERE customer_id = @p_customer_id

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

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语句并传递存储过程的字段。

它还具有不锁定记录的优点-因为我们都知道记录在不应该被保留时最终将保持锁定状态。

来源
Translate

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

来源
Translate

和我在一起,最好的方法是我有一个列lastupdate(时间戳数据类型)。当选择和更新只是比较这个值这个解决方案的另一个进步是,你可以使用此列追查时间数据的变化。我认为如果仅创建像isLock这样的列来更新支票是不好的。

来源