









原文地址:http://blog.csdn.net/wyzxg/archive/2009/11/20/4842769.aspx
author:skate
time:2009-11-20
最近我们的一套总是报 ORA-08177: 无法连续访问此事务处理,刚开始以为是系统压力大,并发一起的,但最近发现,及时系统压力小时,也会报这个错误,于是上网仔细查找,发现下面的文章,让我收益非浅
今天在消息的接受日志中,发现一个错误.ORA-08177: 无法连续访问此事务处理.
觉得有点束手无策,于是停下许多工作,开始解决此错误.
首先怀疑,错误就是并发造成.根据日志显示,同一秒内,处理了7,8笔数据.所以就先从这里下手.
后根据ORA-08177在网上查处错误解释.
Cannot serialize access 不能序列访问.说是Oracle中比较郁闷的 错误.
后来找到一个重现的例子.如下:
这个问题是由oracle 事务隔离级别引起的
在一个事务中执行
update t set object_type='zl' where object_id=17286
不要 提交此事务
然后再其他事务中执行
set transaction isolation level serializable;
update t set object_type='zl' where object_id=17286
这个时候事务2 会等待事务1执行完成,提交事务1 的时候会出现上述问题
我把SQL改成操作的对应消息的表,发现的确如此.但是其中最重要的一句话是set transaction isolation level serializable;就是将这个事务,序列化,如下所述:
隔离级别(isoation eve)
隔离级别定义了事务与事务之间的隔离程度。
隔离级别与并发性是互为矛盾的:隔离程度越高,数据库的并发性越差;隔离程度越低,数据库的并发性越好。
ANSI/ISO SQ92标准定义了一些数据库操作的隔离级别:
通过一些现象,可以反映出隔离级别的效果。这些现象有:
下面是隔离级别及其对应的可能出现或不可能出现的现象
| Dirty Read | NonRepeatabe Read | Phantom Read | |
| Read uncommitted | Possible | Possible | Possible |
| Read committed | not possible | Possible | Possible |
| Repeatabe read | not possible | not possible | Possible |
| Seriaizabe | not possible | not possible | not possible |
ORACE的隔离级别
ORACE提供了SQ92标准中的read committed和seriaizabe,同时提供了非SQ92标准的read-ony。
read committed:
seriaizabe:(串行执行事务,并发性最小)
如果有在seriaizabe事务开始时未提交的事务在seriaizabe事务结束之前修改了seriaizabe事务将要修改的行并进行了提交,则seriaizabe事务不会读到这些变更,因此发生无法序列化访问的错误。(换一种解释方法:只要在seriaizabe事务开始到结束之间有其他事务对seriaizabe事务要修改的东西进行了修改并提交了修改,则发生无法序列化访问的错误。)
ORACE在数据块中记录最近对数据行执行修改操作的N个事务的信息,目的是确定本事务开始时,是否存在未提交的事务修改了本事务将要修改的行。
read-ony:
read committed和seriaizabe的区别和联系:
事务1先于事务2开始,并保持未提交状态。事务2想要修改正被事务1修改的行。事务2等待。如果事务1回滚,则事务2(不论是read committed还是seriaizabe方式)进行它想要做的修改。如果事务1提交,则当事务2是read committed方式时,进行它想要做的修改;当事务2是seriaizabe方式时,失败并报错“Cannot seriaize access”,因为事务2看不见事务1提交的修改,且事务2想在事务1修改的基础上再做修改。
即seriaizabe不允许存在事务嵌套
read committed和seriaizabe可以在ORACE并行服务器中使用。
关于SET TRANSACTION READ WRITE:read write和read committed 应该是一样的。在读方面,它们都避免了脏读,但都无法实现重复读。虽然没有文档说明read write在写方面与read committed一致,但显然它在写的时候会加排他锁以避免更新丢失。在加锁的过程中,如果遇到待锁定资源无法锁定,应该是等待而不是放弃。这与 read committed一致。
语句级的读一致性
事务级的读一致性
设置隔离级别
设置一个事务的隔离级别
设置增个会话的隔离级别
两种情况:(1)在事务量大、高性能的计算环境,需要更高的吞吐量和响应时间;(2)事务数少,并且发生幻影和不可重复读的几率的比较低
(1)适合于很少存在两个事务同时修改同一条记录的情况
(2)长事务以只读为主
(3)大型数据库并且每个短事务只修改很少的记录
如此我就在消息的接口中,找到运行SQL的公用方法,发现执行批量SQL的方法,这里将执行事务的级别设置为了Serializable(序列化),就此就真相大白了,剩下的就是商讨如何解决了.
-----end------
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。