学知识就是要较真--对一致性读写的实验研究

本文通过具体案例探讨Oracle数据库中一致性读与写一致性的概念。详细解释了这两种读取方式的区别,并通过实验展示了在并发更新场景下Oracle如何处理脏数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在优快云里经常会遇到一些特别有学习劲头的朋友,有这样一个朋友,在学习Tom的经典书

《oracle 9i/10g编程艺术》 人民邮电出版的
P244 --7.4 写一致

在一致性读 这里遇到些困惑,如下

引用:
create table t ( x int, y int );
insert into t values ( 1, 1 );
commit;
create or replace trigger t_bufer
before update on t for each row
begin
dbms_output.put_line
( 'old.x = ' || : old.x ||
', old.y = ' || : old.y );
dbms_output.put_line
( 'new.x = ' || :new.x ||
', new.y = ' || :new.y );
end;

上面是观察重启动更新触发器

sql1 : UPDATE t SET x = 2 WHERE y = 5;

如果 在更新sql1时,别的会话也在更新这条记录并且把y=5更新也了 y=10
这样oracle 会选择重启动更新,但重启动更新还是有可能会遇到同样的问题


这是一个非常经典的一段描述一致性读和写一致性的段落

看到这么认真的朋友,也激起了我的解答欲。

其实在oracle里保证一致性读写的特点,我自己是通过两个小点来进行归纳的
1. 一致读(Consistent read):“发现”要修改的行时,所完成的获取就是一致读。
2. 当前读(Current read):得到块来实际更新所要修改的行时,所完成的获取就是当前读。

对于query里的查询是一致性读,这时是没有脏数据的。 对于update的时候,重新启动查询,避免脏数据写。

根据这个基本原则,我们一起来做做实验,还是先用上面的trigger,注意这里的trigger和我们这里的知识点没有必然的联系,只是为了更清楚的表现出重新查询这个动作,我们加入的一个类似log的方式。

我们还是用上面的sql来作为例子
不过这里关键的是执行顺序

哪个语句在前面执行, 现在数据库里的数据如下
Data
X Y
4 5

update的语句有两条
SQL1: UPDATE t SET x = 2 WHERE y = 5;
SQL2: UPDATE t SET y=y+1;

如果sql1先执行,那么后面一句sql2 因为会同样update到 y=5的记录,这是sql1还没有提交,读一致性,不会读脏数据库,所以y=5还在,因此sql2会hold住.
我们来提交sql1.看看结果如何
当sql1提交时,sql1执行成功, 数据更新了x=2, 对于sql2来说重启动查询。用新值更新,不过sql1来说y没有发生改变,当SQL2也更新的时候,y是在原值上+1
这时候数据库的值为
X->2 (SQL1作用)
Y->Y+1 (SQL2作用)
X Y
2 6
现在我们反过来,还是用刚才的数据
先执行sql2, 然后执行sql1 看看是怎样的

先执行sql2,由于sql1读一致性,现在脏数据没有提交,读一致性,找到y=5的一条记录,进行更新,所以sql1现在hold住了。当 sql2提及以后, 数据库更新成功y=5已经变成了6叻。 sql1会如果操作了,很简单,对于update的动作来说,重新查询,这时由于重新查询,已经找不到要更新的y=5的记录了,这样也就一条记录都不会 update。

数据库现在的变化为
Y->Y+1 (SQL2作用)
X->4 (SQL1作用) y=5的记录没有叻,所以更新0条记录。

这也就是上面2点的真实表现了。

Oracle 处理修改语句时会完成两类块获取。它会执行:
一致读(Consistent read):“发现”要修改的行时,所完成的获取就是一致读。
当前读(Current read):得到块来实际更新所要修改的行时,所完成的获取就是当前读。

对这样的知识点,是不是大家都这样认真的思考过,总结过了,其实学习就是这样的。当你激发了自己的潜能和兴趣,你会变着法思考着里面的内容

有兴趣的朋友可以,试想一下
这样的case将是这样的结果?

引用:
数据库数据
X Y
---------- ----------
2 5

SQL1
Update t set x = 4 where y = 5;

SQL2
Update t set y = 6 where x = 2;

 


from:http://blog.youkuaiyun.com/inthirties/archive/2009/09/14/4551545.aspx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值