比如一张JSP页面,其页面逻辑是从数据库中查询出一条记录,然后用户对这条记录的某些字段进行修改,最后保存回去。 如果两个用户同时查询同一条记录,并且都进行了部分字段修改,这样保存以后,后发出保存命令的就会将前面保存的结果给冲掉。 也看过一些解决方法,如在数据库表中增加一列,以记录最后修改时间,查询的时候还要记住这个时间,保存的时候再进行对比。但我觉得这个方法非常麻烦,因为有很多表都有类似的问题,而且这个时间值存在什么地方也要精心设计。 高手们都用些什么办法解决呢?
调试欢乐多
这是web系统应用权限的控制问题。不是oracle丢失的问题啊!你给系统的用户有这个记录的update权限了,人家随时都可以修改,一个用户是这样的,N个用户也是这样的。但是有一点是,应该有记录最后修改这个数据记录的用户id的记录,好让别人知道是谁最终修改了此条记录。
UPDATE some_table
SET b = '修改后的值'
SET c = '修改后的值'
WHERE a = '待修改的记录的主键'。 现在假设两个用户(U1和U2)都登录到WEB系统,并且都查询了同一条记录,他们所看到的结果是一样的。U1想修改b字段,而U2想修改c字段,于是他们都在各自电脑的页面上输入新值。 现在U1点击了“保存”按钮,于是数据库记录的b字段被修改。接着,U2随后也点击了“保存”按钮,因为SQL语句是一次修改所有的字段,所以最后的结果是c字段被修改,而b字段又恢复到原先的值。 之所以会这样是因为程序逻辑默认用户对所有字段进行修改,而用户的本意只是修改一条记录中的某些字段。实际上这个问题等价于事务并发访问中的更新丢失问题。
你这样应该是应用的设计问题,不是oracle的问题,oracle用lock的机制,控制了这个问题,对update的语句进行了lock。而其他的seesion不能update痛一条记录。会hold住,知道前一个commit想你说过的这个应用逻辑,我们以前做过类似的,这个需求可以做的很大也可以做的很小,我们的做法是用version的做法,对update的请求会记录一个version,同时update的时候,会根据version来进行判断,和你们加时间是同样的方法。还有一种发现是我们以前的机制,和oracle的lock机制一样,不过就是当有第二个用户准备update同一个对象的时候,告诉该对象已经锁定,但是这样的方式,客户觉得比较麻烦,最后还是使用的第一种方法。