Min*_*ing 7 database concurrency web-applications race-condition
以下是我想在Web应用程序中执行的两个潜在工作流程.
变化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.:-))但在这种情况下,"最后一个用户点击输入键获胜"可能是你能做的最好的.
[注意:论坛会自动重新编号我的编号列表.我不知道如何覆盖它.]