从“修改”按钮的取消,谈数据修改并发冲突的问题

一、引子

公司做的系统,表单录入,主数据维护等功能里,都有个“修改”按钮。在打开表单时,界面模式是只读的、不可修改的,必须点击“修改”按钮,切换到编辑状态,用户才可以修改数据。慢慢的,这个按钮消失了,就是无需点 修改按钮就可以直接修改数据。

闲聊中,我问技术:

我:为啥么有修改按钮了?

技术:用户先麻烦,要求去掉。

我:之前为啥有这个按钮?

技术:。。。。可能是防止误修改数据吧

以上是引子。我说正题,说说这个修改按钮的渊源。

二、修改按钮,申请数据锁

前面技术上说的里有,是以讹传讹传下来的,可以说是瞎说。之前好多优秀的设计遗产都给丢弃了,只保留了形式而丢弃了内容。这就是一个公司没有积累的弊端。

在遥远的90年代,电算化开始,单机财务软件盛行,后来网络兴起,财务软件发生了一个非常重大的进化,到了网络版财务软件阶段。网络化,带来了单机版时代永远不会出现的一个问题:两个人可能会同时修改同一条财务凭证。这就是应用层面的“并发冲突”。这个并发冲突导致的后果就是:你无法预料保存到数据库的数据是不是你所修改的(你的修改可能会直接别别人覆盖掉,而你却不知道)。

开发人员受数据库锁的启发,发明了一种防止并发冲突的机制:修改前先“锁定”这条凭证,修改,保存,释放这条凭证。这是个很伟大又朴素的发明。具体实现就是在界面上增加“修改”按钮。

1、打开凭证(只读)

2、申请修改凭证:点“修改”按钮,申请“修改”这个凭证,如果没有其他人修改这个凭证,就增加一个标志,表示“锁住”这个凭证

3、进入修改状态

4、修改凭证

5、保存,复位标志,“释放”这个凭证。

其中第2步 申请修改凭证,如果申请时,别人正在修改(修改标志为1),申请失败。仍然是只读状态。

这就是“修改”按钮的作用和由来。

三、数据锁的优化

以上方案完美解决了并发冲突的问题。当然实际实现时会有很多细节,比如一位宕机未能释放锁的问题,这都有完整的解决方案。

以上方案的另一个问题是,操作比较麻烦,需要用户主动按一次‘修改’按钮申请锁。因为并发冲突毕竟不是经常发生,所有 修改 按钮就略显多余。技术人员又发明了方案B(以上方案称为方案A)。

方案B的实现是这样的(还是以凭证编辑为例):

1、打开凭证,进入编辑状态

2、修改凭证

3、点保存 按钮保存数据

    (1)检查数据库的数据是否在我们加载之后发生了变化(检查的方法后面说)

    (2)如果发生了变化,表示在我们修改期间,别人修改了数据,并保存了数据,发生的“并发冲突”。系统给出两个选项:

               i)放弃自己的修改

              ii)覆盖其他人的修改。

这个方案,当时90年代最牛逼的开发工具PowerBuilder内置了这种冲突检测支持。他的做法就是,给每条数据生成一个时间戳(timestamp),每次保存,总是修改这个时间戳。通过比较数据加载时的时间戳 与 保存数据时,数据库中的时间戳 是否一致,可以判断在加载数据后,数据库中的数据是否发生了变化,来知道是否发生了“修改冲突”。

四、两种方案的比较

我就不比较了,不同的方案,适合不同的业务场景。并发冲突频发的场景,适合方案A,反之方案B更合适。

原文地址:https://www.cnblogs.com/senline/p/data_modify_crash_solution.html