我设计了数据库表(在MS SQL服务器上规范化),并为一个应用程序创建了一个独立的Windows前端,供少数用户用来添加和编辑信息。我们将添加一个Web界面,以便日后在我们的生产区域进行搜索。
我担心如果两个用户开始编辑同一个记录,那么提交更新的最后一个将是“赢家”,重要信息可能会丢失。我想到了许多解决方案,但我不确定是否会引起更大的麻烦。
有没有更好的解决方案,还是应该选择其中一种?
答案 0 :(得分:14)
如果您预计不常发生碰撞,Optimistic Concurrency可能是您最好的选择。
Scott Mitchell撰写了一份关于实施该模式的综合教程:
Implementing Optimistic Concurrency
答案 1 :(得分:2)
经典方法如下:
当用户开始编辑时,请执行以下操作:
释放锁
保存记录时,将标志设置为false
答案 2 :(得分:1)
@Mark Harrison:SQL Server不支持该语法(SELECT ... FOR UPDATE
)。
SQL Server等效项是SELECT
语句提示UPDLOCK
。
有关详细信息,请参阅SQL Server Books Online。
答案 3 :(得分:1)
另一个选择是测试您正在更改的记录中的值是否与启动时的值相同:
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语句并传递 new 和 old 存储过程的字段。
它还有一个优点,就是你没有锁定记录 - 因为我们都知道记录最终会在它们不应该被锁定时保持锁定...
答案 4 :(得分:1)
SELECT FOR UPDATE和等价物是很好的,只要您保持锁定一段时间,但是对于宏观数量(例如,用户已加载数据并且没有按下'保存',您应该使用上面的乐观并发(我一直认为这是错误的 - 它比'最后作家获胜'更悲观,这通常是唯一考虑的其他选择。)
答案 5 :(得分:1)
- 首先创建归档(更新时间)以存储最后更新记录 - 当任何用户选择记录保存选择时间时, 比较选择时间和更新时间字段if(更新时间)> (选择时间)表示另一个用户在选择记录
之后更新此记录答案 6 :(得分:0)
数据库将为您完成此操作。看看“选择...更新”,这是专门为这种事情设计的。它将为您提供所选行的写锁定,然后您可以提交或回滚。
答案 7 :(得分:0)
对我来说,最好的方法是使用lastupdate列(timetamp数据类型)。 选择和更新时只需比较此值 此解决方案的另一个进步是您可以使用此列来跟踪数据更改的时间。 我认为,如果您只是创建一个像isLock这样的列用于检查更新,那就不好了。