比如一张JSP页面,其页面逻辑是从数据库中查询出一条记录,然后用户对这条记录的某些字段进行修改,最后保存回去。      如果两个用户同时查询同一条记录,并且都进行了部分字段修改,这样保存以后,后发出保存命令的就会将前面保存的结果给冲掉。      也看过一些解决方法,如在数据库表中增加一列,以记录最后修改时间,查询的时候还要记住这个时间,保存的时候再进行对比。但我觉得这个方法非常麻烦,因为有很多表都有类似的问题,而且这个时间值存在什么地方也要精心设计。      高手们都用些什么办法解决呢?

解决方案 »

  1.   


    这是web系统应用权限的控制问题。不是oracle丢失的问题啊!你给系统的用户有这个记录的update权限了,人家随时都可以修改,一个用户是这样的,N个用户也是这样的。但是有一点是,应该有记录最后修改这个数据记录的用户id的记录,好让别人知道是谁最终修改了此条记录。
      

  2.   

         怪我没说清楚。      假设现在数据库中有一张表,表名为some_table,包含三个字段a,b,c,假设都是char型。字段a为主键,不可修改。      然后JSP页面上包含两个文本框,分别对应一条记录的b和c字段,另外还包含一个“保存”按钮。这个保存按钮触发一条SQL语句:
          UPDATE some_table
         SET b = '修改后的值'
         SET c = '修改后的值'
         WHERE a = '待修改的记录的主键'。      现在假设两个用户(U1和U2)都登录到WEB系统,并且都查询了同一条记录,他们所看到的结果是一样的。U1想修改b字段,而U2想修改c字段,于是他们都在各自电脑的页面上输入新值。      现在U1点击了“保存”按钮,于是数据库记录的b字段被修改。接着,U2随后也点击了“保存”按钮,因为SQL语句是一次修改所有的字段,所以最后的结果是c字段被修改,而b字段又恢复到原先的值。      之所以会这样是因为程序逻辑默认用户对所有字段进行修改,而用户的本意只是修改一条记录中的某些字段。实际上这个问题等价于事务并发访问中的更新丢失问题。     
      

  3.   


    你这样应该是应用的设计问题,不是oracle的问题,oracle用lock的机制,控制了这个问题,对update的语句进行了lock。而其他的seesion不能update痛一条记录。会hold住,知道前一个commit想你说过的这个应用逻辑,我们以前做过类似的,这个需求可以做的很大也可以做的很小,我们的做法是用version的做法,对update的请求会记录一个version,同时update的时候,会根据version来进行判断,和你们加时间是同样的方法。还有一种发现是我们以前的机制,和oracle的lock机制一样,不过就是当有第二个用户准备update同一个对象的时候,告诉该对象已经锁定,但是这样的方式,客户觉得比较麻烦,最后还是使用的第一种方法。
      

  4.   

    应该就是加时间戳 或版本号的方法解决 ,提高 update的 粒度,只针对确实要修改的字段做update可以一定程度缓解这个问题
      

  5.   

    就是并发事务控制问题.6楼说的是. 或者在update时候,把原来select出来的b,c的值也带上.这样,如果被修改了,就会更新不到数据,提示用户重操作.