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 会选择重启动更新,但重启动更新还是有可能会遇到同样的问题 接下oralce 会怎么做thomas kyte 的expert oracle database architecture 9i and 10g programming techniques and solutionsoracle 9i/10g编程艺术 人民邮电出版的 P244 --7.4 写一致
如果 在更新sql1时,别的会话也在更新这条记录并且把y=5更新也了 y=10 这样oracle 会选择重启动更新,但重启动更新还是有可能会遇到同样的问题 这个是看哪个语句在前面执行, Data X Y 4 5SQL1 UPDATE t SET x = 2 WHERE y = 5; SQL2 UPDATE t SET y=y+1; 如果sql1先执行,那么后面一句sql2 因为会同样update到 y=5的记录所以会hold住,当sql1提交时,对于sql2来说重启动查询。用新值更新,不过sql1来说y没有发生改变,当SQL2也更新的时候,y是在原值上+1 此时数据库结果为 X->2 (SQL1作用) Y->Y+1 (SQL2作用)X Y 2 6如果是sql2先执行的话,由于sql1需要更新同样记录,所以也hold住,当sql2提及以后,Y->Y+1更新为新的值为6,此时sql1重启动,此时已经找不到记录为5的行了,所以没有记录被update。提交以后数据 只是单纯的Y+1这里thomas用trigger来解释,不要被误导了,这里只所以加入了trigger,是thomas用来给我们进行观察的,去掉trigger一样。
有兴趣做 把 update t set y = y+1 where y=5;加进去一起试试看。
用这个更过瘾 X Y ---------- ---------- 2 5SQL1 Update t set x = 4 where y = 5;SQL2 Update t set y = 6 where x = 2;Oracle 处理修改语句时会完成两类块获取。它会执行: 一致读(Consistent read):“发现”要修改的行时,所完成的获取就是一致读。 当前读(Current read):得到块来实际更新所要修改的行时,所完成的获取就是当前读。
如果sql1先执行,那么后面一句sql2 因为会同样update到 y=5的记录所以会hold住, hold 住是锁住的意思吗 当sql1提交时,对于sql2来说重启动查询。用新值更新,不过sql1来说y没有发生改变,当SQL2也更新的时候,y是在原值上+1当重启时,y的值已经变了,它当前读取也能读出来吗
..你的逻辑怎么这么混乱 你的两个问题 1 HOLD就是锁住的意思 2 SQL1 UPDATE t SET x = 2 WHERE y = 5; y值明明没有改变啊
等LZ贴出来具体内容再来看看
=========================================================================================
BTW: 前阵子也在看TOM的那本书,由于我也是初学ORACLE,里面有很多代码都看不太明白。
不过原理讲的是挺好的。觉得前面的几章比较侧重管理方面,后面就侧重开发了。
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 会选择重启动更新,但重启动更新还是有可能会遇到同样的问题
接下oralce 会怎么做thomas kyte 的expert oracle database architecture 9i and 10g programming techniques and solutionsoracle 9i/10g编程艺术 人民邮电出版的
P244 --7.4 写一致
这样oracle 会选择重启动更新,但重启动更新还是有可能会遇到同样的问题 这个是看哪个语句在前面执行,
Data
X Y
4 5SQL1 UPDATE t SET x = 2 WHERE y = 5;
SQL2 UPDATE t SET y=y+1;
如果sql1先执行,那么后面一句sql2 因为会同样update到 y=5的记录所以会hold住,当sql1提交时,对于sql2来说重启动查询。用新值更新,不过sql1来说y没有发生改变,当SQL2也更新的时候,y是在原值上+1
此时数据库结果为
X->2 (SQL1作用)
Y->Y+1 (SQL2作用)X Y
2 6如果是sql2先执行的话,由于sql1需要更新同样记录,所以也hold住,当sql2提及以后,Y->Y+1更新为新的值为6,此时sql1重启动,此时已经找不到记录为5的行了,所以没有记录被update。提交以后数据
只是单纯的Y+1这里thomas用trigger来解释,不要被误导了,这里只所以加入了trigger,是thomas用来给我们进行观察的,去掉trigger一样。
有兴趣做
把
update t set y = y+1 where y=5;加进去一起试试看。
---------- ----------
2 5SQL1
Update t set x = 4 where y = 5;SQL2
Update t set y = 6 where x = 2;Oracle 处理修改语句时会完成两类块获取。它会执行:
一致读(Consistent read):“发现”要修改的行时,所完成的获取就是一致读。
当前读(Current read):得到块来实际更新所要修改的行时,所完成的获取就是当前读。
如果sql1先执行,那么后面一句sql2 因为会同样update到 y=5的记录所以会hold住,
hold 住是锁住的意思吗
当sql1提交时,对于sql2来说重启动查询。用新值更新,不过sql1来说y没有发生改变,当SQL2也更新的时候,y是在原值上+1当重启时,y的值已经变了,它当前读取也能读出来吗
你的两个问题
1
HOLD就是锁住的意思
2
SQL1 UPDATE t SET x = 2 WHERE y = 5;
y值明明没有改变啊
只是单纯的Y+1 也就是说,如果sql2先提交 ,sql1重启更新,找不到记录为5的行了,所以没有记录被update这么说sql1也没更新记录了吗?非常谢谢
inthirties这几天热心地回贴,真是个热心肠的好人!
是的,当重新查询发现y=5已经没有了,所以update 0条记录了掌握这个知识点的要点是Oracle 处理修改语句时会完成两类块获取。它会执行:
一致读(Consistent read):“发现”要修改的行时,所完成的获取就是一致读。
当前读(Current read):得到块来实际更新所要修改的行时,所完成的获取就是当前读。在确认哪些记录需要修改时, 是一致性读在update提交的时候,是当前读。