热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

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

Oracle数据库通过undo保证一致性读和不发生脏读不发生脏读,用户A对表更新了,没有提交,用户B对进行查询,没有提交的更新不能出现在用户的查询结果中。实例模拟:表test中的数据如下1,用户A查询:SQL>select...SyntaxHighlighter.all()

Oracle数据库通过undo保证一致性读和不发生脏读
 
不发生脏读,用户A对表更新了,没有提交,用户B对进行查询,没有提交的更新不能出现在用户的查询结果中。
 
实例模拟:表test中的数据如下
1,用户A查询:SQL> select * from test;
        ID NAME
---------- ----------
         1 A
         2 B
2,用户B:update test set name='C' where id=1;没有提交
  www.2cto.com  
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进制:
  www.2cto.com  
select to_number('0080048c','XXXXXXXXXXXXXXX') from dual 得到值8389772
 
在通过下面的语句得到数据块信息:select dbms_utility.data_block_address_file(8389772), dbms_utility.data_block_address_block(8389772) from dual;
 
将其内容dump出来
。。。。
 
KDO Op code:  21 row dependencies Disabled
  xtype: XAxtype KDO_KDOM2 flags: 0x00000080  bdba: 0x01001a3d  hdba: 0x01001a3b
itli: 2  ispac: 0  maxfr: 4858
vect = 3
col  1: [ 1]  41
End dump data blocks tsn: 1 file#: 2 minblk 1164 maxblk 1164
 
发现其值为41(16进制对应的是A),所以用户A看的值为A。
 
假设某一个用户A在6点对某一个表发出了一个查询数据量很大的数据,需要15分钟才能把结果完全查询出来,在这期间,6点10分用户B对数据进行了更新并提交了,用户A查询的结果仍然是6点时候的表的数据,用户B更新的数据不出现在用户A的查询结果中,这就是一致性读。
 
实例模拟:  www.2cto.com  
 
1,用户查询一个需要长时间运行的报表:
 
SQL> variable c refcursor;
SQL> exec open :c for select * from test;
PL/SQL procedure successfully completed.
【这里打开cursor但是不取数据,暂停,然后让用户B更新数据】
 
2,用户B :update test set name='C' where id=1;并且提交。
 
3,SQL> print :c;
        ID NAME
---------- ----------
         1 A
         2 B
 
用户B更新数据而且提交了,但是发现用户A得到的结果集仍然是刚开始执行是表中的数据结果。
  www.2cto.com  
其原理是用户A在执行开始的时候会保存当时的SCN,在每次从数据块读的时候,会比较保存的SCN和数据块的SCN,如果发现数据块的SCN比保存的SCN小,则数据没有变化,直接从数据块读,如果数据块的大,则需要从undo段中读取。select dbms_flashback.get_system_change_number from dual;可以看到当前的SCN.
 
一个查询如果耗费很长时间,而查询的结果在查询的阶段被更改了,而且对应着undo段的数据已经被清理了,就会发生Oracle中著名的ORA-013555: snapshot too old(快照太久)错误。
 
如果一条数据在一个时间段被更新多次并提交了,后放入undo段的块会记录相对以的块上次放在undo段中的块地址,从而可以一直寻找到比开始查询时候记录的SCN小的那个undo段中的数据块。
 
 
作者 kkdelta

推荐阅读
  • 本文详细介绍了IBM DB2数据库在大型应用系统中的应用,强调其卓越的可扩展性和多环境支持能力。文章深入分析了DB2在数据利用性、完整性、安全性和恢复性方面的优势,并提供了优化建议以提升其在不同规模应用程序中的表现。 ... [详细]
  • 本文介绍了如何使用 PostgreSQL 的 `UPDATE ... FROM` 语法,通过映射表实现对多行记录进行高效的批量更新。这种方法不仅适用于单列更新,还支持多列的同时更新。 ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 构建基于BERT的中文NL2SQL模型:一个简明的基准
    本文探讨了将自然语言转换为SQL语句(NL2SQL)的任务,这是人工智能领域中一项非常实用的研究方向。文章介绍了笔者在公司举办的首届中文NL2SQL挑战赛中的实践,该比赛提供了金融和通用领域的表格数据,并标注了对应的自然语言与SQL语句对,旨在训练准确的NL2SQL模型。 ... [详细]
  • 本文详细介绍了HTML中标签的使用方法和作用。通过具体示例,解释了如何利用标签为网页中的缩写和简称提供完整解释,并探讨了其在提高可读性和搜索引擎优化方面的优势。 ... [详细]
  • 数据库内核开发入门 | 搭建研发环境的初步指南
    本课程将带你从零开始,逐步掌握数据库内核开发的基础知识和实践技能,重点介绍如何搭建OceanBase的开发环境。 ... [详细]
  • 本文深入探讨 MyBatis 中动态 SQL 的使用方法,包括 if/where、trim 自定义字符串截取规则、choose 分支选择、封装查询和修改条件的 where/set 标签、批量处理的 foreach 标签以及内置参数和 bind 的用法。 ... [详细]
  • 使用C#开发SQL Server存储过程的指南
    本文介绍如何利用C#在SQL Server中创建存储过程,涵盖背景、步骤和应用场景,旨在帮助开发者更好地理解和应用这一技术。 ... [详细]
  • 本文探讨了适用于Spring Boot应用程序的Web版SQL管理工具,这些工具不仅支持H2数据库,还能够处理MySQL和Oracle等主流数据库的表结构修改。 ... [详细]
  • 本文详细介绍了如何通过多种编程语言(如PHP、JSP)实现网站与MySQL数据库的连接,包括创建数据库、表的基本操作,以及数据的读取和写入方法。 ... [详细]
  • 在当前众多持久层框架中,MyBatis(前身为iBatis)凭借其轻量级、易用性和对SQL的直接支持,成为许多开发者的首选。本文将详细探讨MyBatis的核心概念、设计理念及其优势。 ... [详细]
  • 在使用 DataGridView 时,如果在当前单元格中输入内容但光标未移开,点击保存按钮后,输入的内容可能无法保存。只有当光标离开单元格后,才能成功保存数据。本文将探讨如何通过调用 DataGridView 的内置方法解决此问题。 ... [详细]
  • 本文详细介绍了如何在 Linux 平台上安装和配置 PostgreSQL 数据库。通过访问官方资源并遵循特定的操作步骤,用户可以在不同发行版(如 Ubuntu 和 Red Hat)上顺利完成 PostgreSQL 的安装。 ... [详细]
  • 如何在PostgreSQL中查看数据表
    本文将指导您使用pgAdmin工具连接到PostgreSQL数据库,并展示如何浏览和查找其中的数据表。通过简单的步骤,您可以轻松访问所需的表结构和数据。 ... [详细]
  • 利用存储过程构建年度日历表的详细指南
    本文将介绍如何使用SQL存储过程创建一个完整的年度日历表。通过实例演示,帮助读者掌握存储过程的应用技巧,并提供详细的代码解析和执行步骤。 ... [详细]
author-avatar
txwd2008
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有