如何处理Web应用程序中的并发更改?

Min*_*ing 7 database concurrency web-applications race-condition

以下是我想在Web应用程序中执行的两个潜在工作流程.

变化1

  • 用户发送请求
  • 服务器读取数据
  • 服务器修改数据
  • 服务器保存修改后的数

变化2:

  • 用户发送请求
  • 服务器读取数据
  • 服务器向用户发送数据
  • 用户发送修改请求
  • 服务器保存修改后的数

在每种情况下,我都想知道:确保对此服务的并发访问能够产生合理结果的标准方法是什么?(即没有人的编辑被破坏,值对应于编辑的某些顺序,等等)

情况是假设的,但这里有一些细节,我可能需要在实践中处理这个问题:

  • Web应用程序,但语言未指定
  • 可能,使用Web框架
  • 数据存储是SQL关系数据库
  • 所涉及的逻辑太复杂,无法在查询中表达,例如value = value + 1

我觉得我宁愿不尝试在这里重新发明轮子.当然,这些是众所周知的解决方案中众所周知的问题.请指教.

谢谢.

Jay*_*Jay 6

据我所知,这个问题没有一般解决方案.

问题的根源在于用户可以在进行更新和保存之前检索数据并在屏幕上长时间盯着它.

我知道三种基本方法:

  1. 当用户读取数据库时,锁定记录,并且在用户保存任何更新之前不要释放.在实践中,这是非常不切实际的.如果用户打开屏幕,然后在不保存的情况下去吃午餐怎么办?或者回家过一天?或者是如此沮丧地试图更新这个愚蠢的记录,他退出并永远不会回来?

  2. 将更新表达为增量而不是目的地.举一个典型的例子,假设您有一个记录库存中库存的系统.每次进行销售时,您必须从库存盘点中减去1(或更多).

所以说现有的数量是10.用户A创造销售.当前数量= 10.用户B创建销售.他还获得当前数量= 10.用户A输入两个单位出售.新数量= 10 - 2 = 8.保存.用户B输入一个售出的单位.新数量= 10(他加载的值) - 1 = 9.保存.显然,出了点问题.

解决方案:写入"更新库存集数量=数量-1,其中itemid = 12345",而不是写"更新库存集数量= 9,其中itemid = 12345".然后让数据库对更新进行排队.这与策略#1非常不同,因为数据库只需要锁定记录足够长的时间来读取它,进行更新并编写它.当有人盯着屏幕时,它不必等待.

当然,这仅适用于可以表示为delta的更改.如果你是,比如说,更新客户的电话号码,那就不行了.(比如,旧数字是555-1234.用户A表示将其更改为555-1235.这是+1的变化.用户B表示将其更改为555-1243.这是+9的变化.所以总变化是+10,客户的新号码是555-1244.:-))但在这种情况下,"最后一个用户点击输入键获胜"可能是你能做的最好的.

  1. 在更新时,检查数据库中的相关字段是否与"from"值匹配.例如,假设您为一家律师事务所工作,为您的客户谈判合同.您有一个屏幕,用户可以在其中输入有关谈判的说明.用户A提出合同记录.用户B提出相同的合同记录.用户A输入他刚刚通过电话与另一方通话,他们同意建议的条款.用户B也试图打电话给另一方,他说他们没有回应电话,他怀疑他们正在阻止他们.用户A单击保存.我们是否希望用户B的评论覆盖用户A?可能不是.相反,我们会显示一条消息,指示自从他读取记录后笔记已被更改,并允许他在决定是继续保存,中止还是输入不同内容之前查看新值.

[注意:论坛会自动重新编号我的编号列表.我不知道如何覆盖它.]