比如某个表,其名字为table1 ,数据较多,比如有10万条;其中有个字段field1 ,所有记录值都是为'0';当A会话 执行 select  * from table1 时;
B会话 正在执行 update  table1 set field1 ='1' where field1='0';两个会话可能都比较消耗时间;假如B会话提前结束;那么A会话查询的结果 
1.field1 所有记录都为'0';
  2.field1 部分记录为'0',部分记录为'1';
  3.field1 所有记录都为'1';我个人认为 是第一种答案,不过不能确定;
还有假如A会话是个游标 
declare  
cursor c_1 is  select  * from table1
begin
  open   c_1;
  loop
      FETCH c_1
      INTO ...;
    if c_1%NOTFOUND then   
     
          close c_1;
          exit;
   end if;
      
  end loop;
end ;
那么 fetch 所有记录后,是不是field1的值也会部分为0,部分为1? 我觉得应该和上面一样,也是都为0;以上结论是我的猜测,不知道真是答案是否有出入?
据说sqlserver 在处理这些情况时的机制和oracle 不一样。
当A会话在读时,也就是 select  * from table1  ,相当于做 select  * from table1  for update 锁住表了;这时候B会话的 update  table1 set field1 ='1' where field1='0'; 会等待A会话做完了才做;
而且有时候B会话等不急就直接不做退出了!
总之,sqlserver在并发处理时很有问题 ,容易产生瓶颈。这个是我同事测试发现的。
我做项目基本没用过sqlserver,如果这样,我就不敢用sqlserver了。http://www.itpub.net/thread-956279-1-1.html
http://www.oracle.com.cn/viewthread.php?tid=130788&extra=page%3D1&frombbs=1

解决方案 »

  1.   

    楼主可以看看oracle的多版本,读一致的并发模型。
    我个人觉得第一个问题应该是1
    第二个问题应该是全都为0.可以考虑这样的问题
    begin
       for x in (select * from t)
       loop
           insert into t values(x.username, x.user_id, x.created);
       end loop;
    end;如果答案是部分为1,部分为0的话,不就死循环了?
      

  2.   

    都是0。读一致性分为:语句一致性、事务一致性
    语句一致性:只读取语句开始时已提交的数据;
    事务一致性:只读取事务开始时已提交的数据;无论此后数据如何改变、提交,均可以通过查询undo tablespace获得前像值。当要读取的前像值被覆盖时,就会提示01555错误(snapshoot too old,快照太旧)。