oracle多版本控制/读一致性和非阻塞读(2)

所谓的读一致性,就是sql语句的结果对于查询开始的时间点来说是一致的! 正是因为这一点,下面的sql语句可以插入可以预知的数据集:

insert into t select * from t;

这个insert 语句在之前得到了一个t 表的读一致性视图,它看不到刚刚插入的数据行,而只是在insert操作刚开始时候的记录行,所以不用担心在Insert过程中,因为不断的插入,导致select 出来的结果无止境的问题,有效的解决了这个看是死循环问题!

非阻塞读

很多数据库为了读取数据的一致性,会在读取的时候加锁,大概分为两种锁的机制:

1.读取的时候,给整张表加上锁,在读取的这一刻不允许数据更新,

2.或者缩小到数据级,在读取到的数据行进行锁定,又称为(共享读锁);

无论是哪一种都会对高并发产生性能影响,oracle对读取没有进行加锁,那他又是如何做的呢,现假如一个表结构如下:

create table t_name (c_id number ,c_num number );
--并且插入三条测试数据
insert into t_name values (1,300);
insert into t_name values (2,400);
insert into t_name values (3,500);

--现在有 一个查询需要计算总的分数为多少
select sum(c_num) from t_name;

sum(c_num)
---------------
  1200

 高并发环境下,阻塞读取是当查询到第二条数据的时候,另外一个线程将c_id为1的分数减掉150,并且附加到c_id=3的记录上;

 

当查询到第三条数据(c_id=3)的时候,由于数据更新给c_id=3的记录进行了加锁,所以查询被阻塞了!等待锁的释放,之后查询得到c_num = 650;

 

--现在有 一个查询需要计算总的分数为多少
select sum(c_num) from t_name;

sum(c_num)
---------------
  1350

 在oracle中,查询到c_id=3,发现存在数据修改(数据被加锁了)!那么他会回到查询c_id=1的时间点上,然后从回滚段中获取c_id=3的数据 c_num=500;数据是否加锁不会对其产生影响! 最后的查询结果:

--现在有 一个查询需要计算总的分数为多少
select sum(c_num) from t_name;

sum(c_num)
---------------
  1200

 

猜你喜欢

转载自teachertina.iteye.com/blog/1757388
今日推荐