oracle发生重启动的介绍
来源:互联网 发布:房地产网络推广软文 编辑:程序博客网 时间:2024/05/18 12:37
重启动发生的原因:where条件读取时采用一致读和更新时采取当前读版本不一致造成
Oracle在执行DML语句时,会用到两种不同的方式去读取数据块:
1. 一致读:在“找到”需要修改的数据行时,会采用 consistent read
2. 当前读:在“获取”数据块来实际更新数据行时,会采用 current read
如更新这个语句update test set x=1 where y=1;
首先Oracle会利用一致读找到所有y=1的数据行,因此就算读取期间有别的会话修改了某一行的y值(如从y=1变为 y=2),
Oracle也会利用undo数据将该行的y列恢复到读取的那个时刻的值(即y=1),所以这一行还是会被读取。然后,当要实际更新这一行的时候,
Oracle会利用当前读去获取数据块的最新版本,由于被提交过了,所以读到的y值是2,与之前一致读中的y=1不符。
所以Oracle就知道了需要 “重启动”这个update操作。
Oracle重启动的流程:
1. 回滚之前的修改操作
2. 进入select for update模式,锁定需要修改的行
3. 对锁定的行进行修改操作
(这个流程是指在Oracle默认的READ COMMITED隔离级别下,如果是SERIALIZABLE模式,则会出现ORA-08177错误)
重启动查看(通过创建触发器来查看)
create table t (x int,y int);
insert into t values(1,1);commit;
create or replace trigger t_buffer 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='||:old.x||',new.y='||:old.y);
end;
update t set x=x+1 where x>0;
输出结果如下:
old.x=1,old.y=1
new.x=1,new.y=1
在第二个会话中执行
update t set x=x+1 where x>0; --被锁定
将第一个会话中提交后,输出结果如下:
old.x=1,old.y=1
new.x=1,new.y=1
old.x=2,old.y=1
new.x=2,new.y=1
where条件改成y=0也一样 在第一个会话中执行如下语句
update t set x=x+1 where y>0;
old.x=3,old.y=1
new.x=3,new.y=1
在第二个会话中执行
update t set x=x+1 where y>0;
old.x=3,old.y=1
new.x=3,new.y=1
old.x=4,old.y=1
new.x=4,new.y=1
修改触发器如下:
create or replace trigger t_buffer before update on t for each row
begin
dbms_output.put_line ('已更新');
end;
第一个会话
update t set x=x+1 where x>0;
输出结果:
已更新
第二个会话
update t set x=x+1 where x>0;
输出结果:
已更新
已更新
如果where条件改成y>0,那么就不会引发重启动
第一个会话
update t set x=x+1 where y>0;
输出结果:
已更新
第二个会话
update t set x=x+1 where y>0;
输出结果:
已更新
结果说明:说明:old和:new值在触发器引用时,也会被oracle用于完成重启动检查。where子句中查找行所用的列集会与行触发器中引用的列进行比较,行的一致读版本会与行的当前读版本比较,只要不同,就会重启动修改。
如果 after for each row 触发器比使用 before for each row 触发器更有效,如果使用after for each row 触发器就不会引发重启动问题。
Oracle在执行DML语句时,会用到两种不同的方式去读取数据块:
1. 一致读:在“找到”需要修改的数据行时,会采用 consistent read
2. 当前读:在“获取”数据块来实际更新数据行时,会采用 current read
如更新这个语句update test set x=1 where y=1;
首先Oracle会利用一致读找到所有y=1的数据行,因此就算读取期间有别的会话修改了某一行的y值(如从y=1变为 y=2),
Oracle也会利用undo数据将该行的y列恢复到读取的那个时刻的值(即y=1),所以这一行还是会被读取。然后,当要实际更新这一行的时候,
Oracle会利用当前读去获取数据块的最新版本,由于被提交过了,所以读到的y值是2,与之前一致读中的y=1不符。
所以Oracle就知道了需要 “重启动”这个update操作。
Oracle重启动的流程:
1. 回滚之前的修改操作
2. 进入select for update模式,锁定需要修改的行
3. 对锁定的行进行修改操作
(这个流程是指在Oracle默认的READ COMMITED隔离级别下,如果是SERIALIZABLE模式,则会出现ORA-08177错误)
重启动查看(通过创建触发器来查看)
create table t (x int,y int);
insert into t values(1,1);commit;
create or replace trigger t_buffer 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='||:old.x||',new.y='||:old.y);
end;
update t set x=x+1 where x>0;
输出结果如下:
old.x=1,old.y=1
new.x=1,new.y=1
在第二个会话中执行
update t set x=x+1 where x>0; --被锁定
将第一个会话中提交后,输出结果如下:
old.x=1,old.y=1
new.x=1,new.y=1
old.x=2,old.y=1
new.x=2,new.y=1
where条件改成y=0也一样 在第一个会话中执行如下语句
update t set x=x+1 where y>0;
old.x=3,old.y=1
new.x=3,new.y=1
在第二个会话中执行
update t set x=x+1 where y>0;
old.x=3,old.y=1
new.x=3,new.y=1
old.x=4,old.y=1
new.x=4,new.y=1
修改触发器如下:
create or replace trigger t_buffer before update on t for each row
begin
dbms_output.put_line ('已更新');
end;
第一个会话
update t set x=x+1 where x>0;
输出结果:
已更新
第二个会话
update t set x=x+1 where x>0;
输出结果:
已更新
已更新
如果where条件改成y>0,那么就不会引发重启动
第一个会话
update t set x=x+1 where y>0;
输出结果:
已更新
第二个会话
update t set x=x+1 where y>0;
输出结果:
已更新
结果说明:说明:old和:new值在触发器引用时,也会被oracle用于完成重启动检查。where子句中查找行所用的列集会与行触发器中引用的列进行比较,行的一致读版本会与行的当前读版本比较,只要不同,就会重启动修改。
如果 after for each row 触发器比使用 before for each row 触发器更有效,如果使用after for each row 触发器就不会引发重启动问题。
- oracle发生重启动的介绍
- Oracle 语句重启动
- oracle 重启动更新
- 重启动
- 【Oracle 11g】我们的触发器竟然触发了两次!——诱因:sql重启动
- /*-------------不带消息提示的重启动计算机-------------*/
- oracle commit的时候发生了什么
- VS.NET安装时反复出现重启动的问题
- resin3.0.22 更新class文件后自动重启动的解决方案。
- Linux的系统停止与重启动命令详解
- 防止中断后系统调用重启动的signal函数。
- oracle-win7安装oracle 10g时发生”程序异常终止。发生内部错误”的提示
- oracle-win7安装oracle 10g时发生”程序异常终止。发生内部错误”的提示
- 发生的方式发生
- 撒发生的发生
- MYSQL的锁介绍,以及死锁发生情况-带例子
- win7安装oracle 10g时发生“程序异常终止。发生内部错误”的提示
- win7安装oracle 10g时发生“程序异常终止。发生内部错误”的提示
- 10个步骤让你成为高效的Web开发者
- Hdoj1863畅通工程
- sqlserver数据库连接池配置和运用总结
- UESTC 1711 Divide 解题报告
- 第四章 从头到尾彻底解析Hash 表算法
- oracle发生重启动的介绍
- C++_友元函数
- On-Disk还是In-Memory:两种数据库对比
- eclipse中android模拟器找不到的解决办法
- 请教:多线程同时写socket是否需要加锁
- Android HTML5 Video视频标签自动播放与自动全屏问题解决
- j2ee 的十三种技术规范
- 第五章 Hash表算法(续)、倒排索引关键词不重复Hash编码
- 【java学习笔记】【特别】Byte输出为二进制字符串的代码