设为首页 加入收藏

TOP

《Oracle编程艺术》学习笔记(13)-Oracle的并发与多版本控制 (二)
2014-11-24 02:08:20 来源: 作者: 【 】 浏览:2
Tags:Oracle 编程 艺术 学习 笔记 -Oracle 并发 版本 控制
这个块读到值$100
T7 提交事务
T8 得到答案sum = $1250


SERIALIZABLE隔离级别和读一致性


使用SERIALIZABLE事务隔离级别在一个环境中操作时,就好像没有别的用户在修改数据库中的数据一样。我们读取的所有行在重新读取时都肯定完全一样,所执行的查询在整个事务期间也总能返回相同的结果。
例如,如果执行以下查询:
select * from ACCOUNTS;
exec dbms_lock.sleep( 60*60*24 );
select * from ACCOUNTS;
2次从ACCOUNTS返回的结果总是一样的,即使是在这个期间别的会话修改了ACCOUNTS的数据。这种情况下,Oracle会使用回滚段按事务开始时数据的原样来重建数据。
但是如果现在我们准备更新某一行,而在这之前(我们第一次执行select * from ACCOUNTS之后),别的事务也更新了这一行,那么就会得到一个错误
ORA-08177: can't serialize access for this transaction
(实际上并不需要是同一行上发生修改,只要包含这一行的块上有其他行已经被修改,就会发生这个错误)

保证以下几点情况下,适合使用SERIALIZABLE隔离级别:
· 一般没有其他人修改相同的数据
· 需要事务级读一致性
· 事务都很短

READ ONLY隔离级别和读一致性
READ ONLY事务与SERIALIZABLE事务惟一的区别是READ ONLY事务不允许修改,因此不会遭遇ORA-08177错误。
在READ ONLY事务中可能会看到ORA-1555:snapshot too old错误。
如果其他的会话正在修改你在READ ONLY事务中读取的数据,就有可能发生这种情况。因为READ ONLY事务需要读取记录在回滚段中的修改前的这些数据(undo信息),把它们恢复到块缓冲区。但是回滚段以一种循环方式使用,这与重做日志非常相似。READ ONLY事务运行的时间越长,重建数据所需的undo信息就越有可能已经被覆盖了,此时,就会得到ORA-1555错误。
对于这个问题,惟一的解决方案就是为系统适当地确定回滚段大小。

热表上超出期望的I/O
使用READ ONLY事务与SERIALIZABLE事务可能导致超出期望的I/O。如果其他的事务大量修改了我们的事务需要读取的记录,就会发生这种现象。原因就是Oracle会查找undo信息,撤销其他事务所做的修改。甚至是其他事务只是很多次反复修改了少量记录,也会造成这种现象,Oracle撤销了修改,把被修改的块从回滚段恢复到块缓冲区,之后发现这个会滚块还是太新,然后继续回滚,反复进行,直到找到事务开始时的那个版本,这就会导致大量的I/O来读取回滚段。(这也说明块缓冲区中可能包含一个块的多个版本)
不仅仅是READ ONLY事务与SERIALIZABLE事务才会有这种现象,如果一个查询语句运行的时间很长,也会有可能遇到同样问题。运行时间越长,可能需要更多工作才能从块缓冲区(通过回滚)获得数据,就可能会运行的更久,这是一个恶性循环。

作者:NowOrNever

首页 上一页 1 2 下一页 尾页 2/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇重置oracle的sys用户密码 下一篇select子句中case end和decode函..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: