WEB应用程序,在多人同时操作同一条记录时,容易发生相互覆盖。
我们的系统采用的是悲观锁,每一条记录都加USER_ID和DATETIME数据项,当一个人进入编辑画面时,首先检查USER_ID是否为空,如果不为空,表明该记录被别人正编辑,不能进入;为空,则允许进入编辑画面,并且更新USER_ID为当前用户,DATETIME为当前时间。退出编辑画面时,则清空USER_ID和DATETIME。现在的主要问题就是退出编辑画面比较难捕获。用的是onunload事件,但很多时候用户通过一些非正常途径退出应用就不会触发这个事件。
不知道大家对解除锁定有没有别的办法能让它更稳定一些?或者对这种锁定机制有没有好的更好的处理办法?

解决方案 »

  1.   

    如果想要的更准确,可以使用ajax+定时器之类的方法去更新状态。
      

  2.   

    to: toury所以向大家请教有没有更好的办法,因为现在手头的项目是多人共同编辑一些数据,所以相互覆盖的几率很大,必须要有锁定机制。to: net_lover,hookee你们说定时器的办法,以前在做在线人员的时候用到过。用定时器一直更新着时间,如果超过了多长时间就视为退出。当时感觉在线人员就很费资源,只不过一个系统一般就一个,所以就没有计较。如果每一个编辑页面都这样,是不是太繁琐了一点。服务器端服务,是个办法,但超过多长时间就视为退出呢?是个比较难确定的,毕竟操作有快有慢。太短,可能别人还没有操作完,太长,那种由于非正规途径退出的锁定的时间又太长了。
      

  3.   

    这个问题我觉得其实就是个超时的问题 我的想法是这样的:
       在Client端可以增加系统服务时间配置(可以指定管理员来配置,也可以所有人都可配置)  
       然后前台需要的地方发ajax或是定时去发请求 这个视情况而定 
       服务端获取这个当前的配置来进行处理 超过了这个时间的话解除锁定也好或是发什么消息也好 总之能够达到效果就行在下愚见,希望不吝指教。
      

  4.   

    我说的“策略有问题”不是指怎么锁定的问题,而是该不该“锁定”的问题。你把注意力放在前者我觉得是治标,考虑后者才是治本。当然,也许是我猜错了你的需求,呵呵。太晚了,我没精力过多描述对你需求的猜测,大致说说我的建议:
    1、你现在的业务逻辑:
    “每一条记录都加USER_ID和DATETIME数据项,当一个人进入编辑画面时,首先检查USER_ID是否为空,如果不为空,表明该记录被别人正编辑,不能进入;为空,则允许进入编辑画面,并且更新USER_ID为当前用户,DATETIME为当前时间。退出编辑画面时,则清空USER_ID和 DATETIME”;2、我建议的业务逻辑:
    1) 每一条记录都加VERSION_LOG数据项,内容为(USER_ID||DATETIME||更改的数据id);这个更改的数据id含义下面会提及;
    2) 可同时编辑。当几个人进入编辑画面时,读出原数据以及VERSION_LOG送到客户端。于是出现“各干各的”状况;
    3)  总有一个人先完成编辑,需要将数据送到服务端进行数据更新。关键点在此:提交前,先AJAX(参数为编辑前的VERSION_LOG)到服务器,检查一下VERSION_LOG,看看USER_ID||DATETIME有没有更新。如果没有,没的说,服务端返回OK给该用户的客户端,那么,本次编辑的数据由这个用户提交服务器,写库。写库时,最好先不要更新数据,而是将数据另外存入一个临时表,然后将临时表的该数据的id放入VERSION_LOG,这样就可以用新的USER_ID||DATETIME||更改的数据id 来更新VERSION_LOG;
    4) 第二个人完成编辑后,同样先AJAX(参数为编辑前的VERSION_LOG)请求服务器的VERSION_LOG,发现VERSION_LOG变了,则以更改的数据id取得前个用户的编辑数据返回给第二个用户的客户端显示出来,让他自己斟酌怎么处理,给出几个选择:
    a)前面的合理,放弃自己的;
    b)坚持我的,还要上传;
    c)覆盖前个用户的更改(此人要有高权限);
    a没的说;b、c需要你们自己去论证如何处理
    5)以此类推,第三个人AJAX,把前两个人的编辑后的数据返回给他,同4)....
    6)如果出现几个人各持己见,那就由他们的大佬最后定夺。
    ========================
    顺便说个小例子,不知道是不是对你有启发:
    一个文本文件,你同时用记事本和ultraEdit打开,当你先在基本里更改并保存后,转到ultraEdit后,会跳出提示。虽然和你的需求不太搭,但可参考。强调一下,上面说的条理也不清楚,仅仅是个建议。
      

  5.   

    to:toury我现在所做的WEB应用,以前的方式是大家通过共享来共同完成一个EXCEL,现在把它做成在线的方式。感觉你说的这个方案,与我现在使用的,有点类似于乐观锁与悲观锁的区别
    我现在使用的,是悲观锁,类似于VSS,只要编辑就锁定数据,这样就不至于冲突。
    你提供的方案,是乐观锁,类似于CVS,在提交时判断是否冲突。如果里面有一个合并功能就更好了,但恰恰这个是很难做的。当然,乐观锁性能更高一些,但考虑的东西也很多,实现起来比较麻烦。
      

  6.   

    1、你也可以将我的建议称之为“乐观锁”。但我之所以没说乐观锁是因为,通常乐观锁只是简单的将控制字段version +1,也就是说,提交更新数据时,只检查新version 是否比原version 的版本号高。而我的建议已经从这个功能上加了附加功能。 至于你说的“如果里面有一个合并功能就更好了,但恰恰这个是很难做的。”我不认同。合并有什么难做的?如果你的业务逻辑已经确定清楚,完全可以把7楼“c)覆盖前个用户的更改(此人要有高权限);”这个改为“合并”。这个问题靠说很难说清楚,不说了。2、如果是EXCEL编辑,不知道你们是不是使用的微软最新WEB OFFICE控件做在线编辑。如果是,在控件里找找保存时有没有说明可以利用的,我没仔细研究过。你不妨试试