例如,a表中的b字段值为10 两进程同时执行 update a set b=b+10;会不会出现a最后值为15的情况oracle有没有相关文档对这种并发情况可能会发生的问题进行描述?

解决方案 »

  1.   

    如果两个update都成功的commit了,那么b肯定是30
      

  2.   

    LZ可以了解下“一致读”与“当前读”的知识,
    以及并发UPDATE时,单纯像LZ这样不带WHERE子句的UPDATE与带WHERE子句的UPDATE的区别。
    如:
    update a set b=b+10; 
    update a set b=(select b+10 from a);
    这两种UPDATE分别对应“当前读”与“一致读”。其结果是完全不一样的。LZ可自行实验下。
      

  3.   

    to 2F:
    这样的情况
    进程1读取b值
    进程2读取b值进程1将所读到的b值+5存进数据库
    进程2将所读到的b值+5存进数据库这样就会出现b为15的情况了
    不知道oracle有没有对这种情况做限制? 是不是要自己程序做好同步?
      

  4.   

    to 3F:
    请问带where和不带where有何区别?我在网上找到,consistent gets :consistent_gets是从回滚段中读到的前映(或叫读取一致性影象), 看见的数据是查询开始的时间点的,所以若存在block在查询开始后发生了变化的情况,则必须产生 before image 然后读数据,这就是一致读的含义
    查询就是表示 consistent gets (query mode),因为查询要保证所获取的数据的时间点的一致性,所以叫一致读,即使是从当前 buffer 获得的数据,也叫 consistent gets ,这仅仅表达一种模式一种期望,并不表示真实的是从 当前buffer 获得 还是从回滚段获取数据产生的 bufore image 。
    db block gets : current mode , 不管这个块上的数据是否可能存在 before image ,也就是说不管是否存在回滚中数据可以 回滚,只看见当前最新块的数据,即使别人正在更新,也看见别人更新状态的数据,比如dml的时候就不需要看见别人更改前的数据,而是看见正在更改的,当然同时,若操作相同数据则被lock住。也就是说一次查询中看见的数据可能不在同一个时间点上,比如一个大的dml,当dml 开始更新一个非常大的表后,这个表更新的过程中,有一个进程去把该表末尾的一个记录更新了,然后这个大更新抵达该记录的时候会被阻塞的,若该进程事物提交,则大更新会覆盖该事务的更新,也就是说,这个大更新所看见的数据是当前的,不具有时间点的一致性,所以叫 current mode但是不知道什么情况下执行的select语句是一致读,什么情况下是当前读?
      

  5.   

    这种情况就需要自己处理了,update语句加where条件或者用select for update