所谓的读一致性,就是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