概述
对于我们做web的来说,都会遇到这样的情况:两个人(或多个人)同时打开同一条数据的修改页面,(如果不做处理)这时候就会发生很不好的现象:最后一个提交表单的人,会把之前所有提交的修改都覆盖掉了!
上面这个现象,我们常常说,这叫并发现象!其实,更专业一点的,这叫“数据的脏更新问题”。这个问题,在一般场景下,其实可以看成是无所谓的事情,但在一些比较严谨的或者“爱计较”的用户来说,这是不能忍的!因为我好不容易更新的东西,居然被别人覆盖了,甚至是一个领导修改完之后,发现居然被别人的修改覆盖了(我们就遇到过这样的现象,客户就向我们投诉了)!
对于上面的现象,我们不讨论要不要解决或有没有必要解决,我们要讨论的是,如果要解决,该怎么解决?我们系统中是解决了的,毕竟是收费客户投诉……
方案探讨
对于这个现象的解决方案来说,我先说几个方案,并讨论一下这几个方案的优缺点,大家可以多补充,一起探讨一下。
- 最简单最有效的,莫过于直接在各个修改的业务代码上加上判断。具体做法时,在进入修改页面时,把当前数据的修改时间(或有能记录数据变更的版本字段就更好)带到页面,在页面的form表单里hidden住,在提交修改时,对比这个时间,与服务器中当前数据的那个字段的值是否相等,如果相等,表示这段时间内没有被别人修改过,可以进行修改保存;否则就给出不能修改的提示。 这个方案的好处是:简单有效,灵活性很高,对不同的表可以取不同的合适的字段做对比信息;但其缺点也很明显:工作量大家、代码分散、维护困难等。
- 比较高端的做法是,在进入某数据的修改页面时,对当前数据加锁(锁的方式可以是数据库锁,也可以是在表中加一个标志字段表示数据正在被修改),这样别人在进入这条数据的修改页面时,系统会自动提示数据有别人在修改,在用户修改完之后将锁释放。 这个方式的优点是,防患于未改,而且因为使用锁机制,可以统一处理,减少工作量并易于后期维护;其缺点特别明显:就在于这个锁的释放!我们的web项目不像C/S结构,我们是无状态的一个交互方式,我们无法知道用户的操作状态,比如,我打开一个修改页面(这时加了锁),然后我直接把页面或浏览器关掉了,这时锁是不释放的,这样这条数据就永远被锁死了!这就得需要想一个特别的方案来释放这些“死锁”数据。
- 比较实际的做法,也是我使用的方法。就是根据自己的项目特征,从框架层面做一些处理。所以,本文将重点探讨一下这种方式的实现及不足之处。
框架层面统一解决脏更新的探讨
这个方案需要有三个基本条件:页面渲染使用统一接口(如Velocity、FreeMark等渲染框架);数据库操作使用统一接口(如Hibernate、ibatis/myBatis等ORM框架,或自定义的统一操作入口);表中要有能做判断的字段。我们的项目使用的是Velocity+SpringMVC+Spring+iBatis(而我又对iBatis的常用操作接口做了封装,如:插入数据,根据id修改数据,根据指定的条件修改数据等等),而我们每个表中都正好有一个updateTime字段(更新时间),每次更新数据时,这个字段都会被更新为最新时间。
有了这三个条件,我们就可以使用以下思路去做:在进入一个页面时,在对页面进行渲染前,我会把当前的页面中所用到的所有的实体类中的updateTime时间获取出来,并getTime()为long类型,做为判断的标志信息,hidden到页面的所有form表单中;在提交表单时,如果有这个hidden信息,则在根据id修改单条数据的接口中做判断。
因为代码在公司研发网络(局域网),无法给出完整代码,这里我把关键地方的代码列出一下:
首先,要新建一个Filter,里面将这个hidden值取出来,放到线程池变量(ThreadLocal)中,这个就不需要写代码了吧?
其次,在渲染页面的地方,重写VelocityLayoutView.renderScreenContent方法,将其最后一行的改为:
velocityContext.put(this.sreenContentKey, appendVersionStamp(velocityContext, sw.toString()));
appendVersionStamp这个方法代码核心如下:
private String appendVersionStamp(Context velocityContext, String pageHtml){ if(StringUtils.isBlank(pageHtml) || (pageHtml.toLowerCase().indexOf("<form ")==-1 &&pageHtml.toLowerCase("<form>").indexOf()==-1)){ return pageHtml;//如果页面内容为空,或没有form表单,则不处理 } //下面的代码比较多,就不写了,大概意思就是:将velocityContext中所有实体类找出来,然后取出其updateTime(如果updateTime为空,则取addTime),将实体类的类名+id+updateTime.getTime,作为一组标志。如果有标志,则把它hidden到每个from表单中,其hidden的name="_update_version_"。 }
再者,在根据id修改数据的接口中对其进行判断,其核心代码如下:
public <T> int updateById(T t){ String version = VerifyHolder.getUpdateVersion();//从线程变量中取出Filter放置的页面提交上来的版本信息 if(StringUtils.isNotEmpty(version)){//表单中有提交时,就可以更新。 //这里的代码比较多,其逻辑为:根据id先从数据库中查出当前数据的updateTime(这里要缓存到线程变量中,因为如果业务中有多次修改操作的话,会引起误判),判断类名+id+updateTime.getTime(),前面类+id一致的情况下(这是确保验证的是同一条数据),如果updateTime不一致,则抛出异常,不给操作,否则就进行更新操作。 } }
优缺点探讨
优点:简洁明了,代码量小,维护方便,最重要的是,对开发透明。
缺点:对系统的要求较多;只能对根据id修改的接口才能做这样的统一处理,其它地方,因为是统一规则,无法个性化处理;
最后说一句:这种思路还可以使用AOP等切面技术实现,但思路是一致的。
欢迎大家参与探讨!
相关推荐
实现自动打包资源,使用MD5码校验一键化CDN更新资源筛选,游戏启动热更新解决方案。脚本使用xlua。使用说明文档及框架源码下载
在此基础上,本文对SSH框架和jQuery技术在Java-Web开发中的应用进行了探讨。同时,本文结合时代技术发展的特点,对基于SSH框架的Java-Web数据库配置设计方法进行了研究,并对基于jQuery技术的Java-Web功能优化设计方法...
在安全协议的形式化分析研究当中,如何在统一的框架下对更多的安全属性进行分析和验证是一个亟待解决的重要问题。为了解决这个问题,提出了用匹配关系来形式化地描述各种安全属性的统一框架,建立了语法和语义系统,...
VTK框架结构与运行机制的探讨,对人们熟悉理解VTK相当有用
Android UI统一框架, 实现复杂维度的UI管理框架, 参考博文: http://blog.csdn.net/ostrichmyself/article/details/8285735
(完整版)不动产统一登记信息应用平台总体技术框架.pdf(完整版)不动产统一登记信息应用平台总体技术框架.pdf(完整版)不动产统一登记信息应用平台总体技术框架.pdf(完整版)不动产统一登记信息应用平台总体技术框架.pdf...
GIS项目管理框架探讨.
本文当为VTK框架结构与运行机制的探讨,面向的是vtk的一些运行机制的阐述,对于刚刚接触vtk的初学者来说有很大的指导意义
OpenDoc项目发起人及《DrBobb’s Journal China 》,Spring能够粘合不同层面的解决方案,但无论是MVC层还是ORM层,Java领域从来都不缺少好的框架,我们在使用Spring时,从这些框架中做选择的依据是什么?
“轻量级Java EE”课程的Spring框架教学改革探讨.pdf
·体系结构框架(ArchitectureFramework)是一种规范化的体系结构描述过程和方法,确保各利益相关方基于统一标准对体系结构进行理解、比较和集成。·从多个视图以及不同抽象层次上对体系结构加以捕获,将复杂的问题...
默认当App启动或唤醒时,客户端会从服务器检测更新,用户可以在设置对话框中进行修改:一天一次或手动检查更新。 除了支持iOS,HokeyKit也支持Android平台,不过Android版还处在Alpha阶段,支持OTA及应用内更新。 为...
人工智能时代中小学生智能素养框架构建及其培养机制探讨.pdf
基于AudioRecord和OpenSL ES两种框架的采集PCM数据功能的统一封装 基于AudioRecord和OpenSL ES两种框架的采集PCM数据功能的统一封装 基于AudioRecord和OpenSL ES两种框架的采集PCM数据功能的统一封装 基于Audio...
详细解析android的框架,从框架层面来剖析Android系统。
理论知识. 客户关系管理基础理论体系框架探讨.
软件项目管理:统一性框架(英文版) 作者: Walker Royce pdg版本,需用超星阅览器
其发展历史从学术领域和研发机构 的运用开始,目前流行的Spring应用程序框架将AOP思想融入了整个框架的设计开发与应用当中。使用Spring框架固然给 我们的编程带来了好处与便利,但是同时存在着一个问题,对于...
自动化测试框架体系探讨,如何去创建自动化测试框架体系,已经对自动化测试框架体系的知识结构梳理!以及自动化测试框架的应用
关于框架结构破坏机制的探讨.doc