Home > Database > Mysql Tutorial > Oracle数据库通过undo保证一致性读和不发生脏读

Oracle数据库通过undo保证一致性读和不发生脏读

WBOY
Release: 2016-06-07 17:09:40
Original
1226 people have browsed it

不发生脏读,用户A对表更新了,没有提交,用户B对进行查询,没有提交的更新不能出现在用户的查询结果中。

不发生脏读,用户A对表更新了,没有提交,用户B对进行查询,,没有提交的更新不能出现在用户的查询结果中。

实例模拟:表test中的数据如下

1,用户A查询:SQL> select * from test;
        ID NAME
---------- ----------
         1 A
         2 B

2,用户B:update test set where id=1;没有提交

3,用户A再次查询:SQL> select * from test;
        ID NAME
---------- ----------
         1 A
         2 B

查询到数据块的信息

select id, rowid, dbms_rowid.rowid_relative_fno(rowid) fn,dbms_rowid.rowid_block_number(rowid) bk from test order by id
这时候dump 数据块(内存中的数据块) alter system dump datafile 4 block 6717,

Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0003.02d.00000323  0x008001c5.0297.0d  C---    0  scn 0x0000.0022cf82
0x02   0x0006.020.00000320  0x0080048c.017d.03  ----    1  fsc 0x0000.00000000
 
。。。。
block_row_dump:
tab 0, row 0, @0x1f90
tl: 8 fb: --H-FL-- lb: 0x2  cc: 2
col  0: [ 2]  c1 02
col  1: [ 1]  43
tab 0, row 1, @0x1f88
tl: 8 fb: --H-FL-- lb: 0x0  cc: 2
col  0: [ 2]  c1 03
col  1: [ 1]  42
end_of_block_dump

发现id=1的值已经更改了,43(16进制对应的是C),那么A用户得到值为什么还是A呢

这是因为Oracle发现这条数据有lb: 0x2 对应的是ITL,从ltl为0x02的记录看到flag为----,表示有事务标记,数据被加锁,需要从undo段的uba(undo block address)中读取。

在undo段中对应的块信息是0x0080048c,这里的数字是16进制的,先将其转为10进制:

select to_number('0080048c','XXXXXXXXXXXXXXX') from dual 得到值8389772

linux

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template