Oracle锁与丢失更新

      丢失更新(lost update)是一个经典的数据库问题。实际上,所有多用户计算机环境都存在这个问题。简单地说,出现下面的情况时(按以下所列的顺序),就会发生丢失更新:
      (1) 会话Session1中的一个事务获取(查询)一行数据,放入本地内存,并显示给一个最终用户User1。
      (2) 会话Session2中的另一个事务也获取这一行,但是将数据显示给另一个最终用户User2。
      (3) User1使用应用修改了这一行,让应用更新数据库并提交。会话Session1的事务现在已经执行。
      (4) User2也修改这一行,让应用更新数据库并提交。会话Session2的事务现在已经执行。

      这个过程称为“丢失更新”,因为第(3)步所做的所有修改都会丢失。例如,请考虑一个员工更新屏幕,这里允许用户修改地址、工作电话号码等信息。应用本身非常简单:只有一个很小的搜索屏幕要生成一个员工列表,然后可以搜索各位员工的详细信息。这应该只是小菜一碟。所以,编写应用程序时没有考虑锁定,只是简单的SELECT和UPDATE命令。

      然后最终用户(User1)转向详细信息屏幕,在屏幕上修改一个地址,单击Save(保存)按钮,得到提示信息称更新成功。还不错,但是等到User1第二天要发出一个税表时,再来检查记录,会发现所列的还是原先的地址。到底出了什么问题?很遗憾,发生这种情况太容易了。在这种情况下,User1查询记录后,紧接着另一位最终用户(User2)也查询了同一条记录;也就是说,在User1读取数据之后,但在她修改数据之前,User2也读取了这个数据。然后,在User2查询数据之后,User1执行了更新,接到成功信息,甚至还可能再次查询看看是否已经修改。不过,接下来User2更新了工作电话号码字段,并单击Save(保存)按钮,完全不知道他已经用旧数据重写(覆盖)了User1对地址字段的修改!之所以会造成这种情况,这是因为应用开发人员编写的程序是这样的:更新一个特定的字段时,该记录的所有字段都会“刷新”(只是因为更新所有列更容易,这样就不用先得出哪些列已经修改,并且只更新那些修改过的列)。

      可以注意到,要想发生这种情况,User1和User2甚至不用同时处理记录。他们只要在大致同一时间处理这个记录就会造成丢失更新。
      我发现,如果GUI程序员在数据库方面的培训很少(或者没有),编写数据库应用程序时就时常会冒出这个数据库问题。这些程序员了解了如何使用SELECT、INSERT、UPDATE和DELETE等语句后,就着手开始编写应用程序。如果开发出来的应用程序有上述表现,就会让用户完全失去对它的信心,特别是这种现象只是随机地、零星地出现,而且在受控环境中完全不可再生(这就导致开发人员误以为是用户的错误)。 
      注:《oracle9i&10g编程艺术》阅读笔记

 

你可能感兴趣的:(oracle,编程,Hibernate,工作)