我的编程空间,编程开发者的网络收藏夹
学习永远不晚

深入理解oracle的事务隔离性

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

深入理解oracle的事务隔离性

转: http://www.bkjia.com/oracle/925189.html


深入理解oracle的事务隔离性


在Oracle关系数据库中,我们先来看下面这个问题:
A事务:select <cols> from T where id > 10 and id < 10000;
B事务:update T set id = 45000 where id = 4501
两个事务按下面的顺序执行:
A事务:|--------------------------------|commit
B事务: |-------------|commit
也就是A事务先开始执行,过一段时间B事务再开始执行,但是B事务先执行完并commit提交了,A事务又过了一段时间才完成。那么问题来了,在这种情况下,问A事务能不能取得正确的结果,两个事务之间会不会有干扰,怎么干扰?
这是一个典型的关系型数据库事务的隔离性问题,而且,针对不同的数据库(存储引擎),可能会有不同的表现。

根据上面的描述,以oracle为例,它的缺省数据库隔离级别是读已提交(read-committed),事务A持有一个读锁(瞬间共享读锁),B持有一个排它写锁。
Read Committed读已提交的官方定义是,通过“瞬间共享读锁”和“排他写锁”实现。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。
按照读已提交的定义,似乎按上题的条件,A,B两个事务都能够正确完成并commit提交。

但关系数据库厂商,它们的产品往往不会完完全全的按照规范来实现,总会附加一些自己特有的东西在里面。那么我们接下来详细分析一下,oracle是怎样处理的,SQL语句执行的内部过程相当复杂,大概比较显式和通俗易懂的是,先运行执行计划,然后执行SQL优化等策略,接着可能根据关键字,进行加锁处理,上下文切换等操作,比如select语句就会加一个读锁。

在执行DML语句时,Oracle会给每一行增加一个sn序列号,比如select <cols> from T where id > 10 and id < 10000;这条语句,查询出将近1w条数据,在执行扫描的时候,发现符合条件的行就会加一个sn(实际操作时,可能是和内存中某个sn数值关联起来),这个sn序列号实际上被当做乐观锁使用。
那么可能出现下面的情况,事务A的select语句还没有执行完,当执行到2000条的时候,B开始了一个update T set id = 45000 where id = 4501的事务,由于在oracle中,写锁的级别高于读锁,因此这时候B事务的update语句取得写锁,成功执行完并commit,交出写锁。
当先开始的select语句执行到4501时,如果此时B事务已经commit,那么A事务会接着执行下去,成功commit,反之,当A事务执行到4501行时,B事务还未commit,那么二者的锁在4501这条数据发生冲突,这时整个A事务就会出错。

这里插一句,对于DML的select语句来说,只具有读一致性,所以失败了仅仅是报错放弃,不会回滚。

然而,上面的描述却有一个知识缺失点,就是所谓的MVCC(Multi-Version Concurrency Control)---基于多版本的并发控制协议 (注:与MVCC相对的,是基于锁的并发控制,Lock-Based Concurrency Control)。MVCC最大的好处是:读不加锁,读写不冲突。在读多写少的OLTP应用中,读写不冲突是非常重要的,极大的增加了系统的并发性能,现阶段几乎所有的RDBMS,都支持了MVCC。

在MVCC并发控制中,读操作可以分成两类:快照读 (snapshot read)与当前读 (current read)。快照读,读取的是记录的可见版本 (有可能是历史版本),不用加锁。当前读,读取的是记录的最新版本,并且,当前读返回的记录,都会加上锁(一种就是上面提及的sn序列号方式的乐观锁),保证其他事务不会再并发修改这条记录。

在oracle里,undo就是所谓的快照。如果undo够大的话,A事务的select返回的是没有执行update的语句前的数据;如果undo不够大,A事务的select会直接报错没有返回值,因为是隐式提交,所以并不会rollback回滚。
这就是oracle的经典错误ORA-01555快照过旧。

再回到一开始的原题目中,当执行事务A的select语句时,并没有明确指出是快照读还是当前读。因此,为严密起见,我们最终的结果是:
1.如果A事务执行的是快照读,如果undo够大的话,A,B事务都能够正确commit提交,A事务的select返回的是没有执行update的语句前的数据;如果undo不够大,B事务能够正确commit,A事务的select会直接报错没有返回值,事实上数据库的读写事务,绝大多数都属于这种情况;
2.如果A事务执行的是当前读,那么当A事务的select读操作和B事务的update写操作没有冲突时(不会同时读写4501那一行),两个事务都能正确执行;反之,A事务是有可能出错的。并不是A事务只要先执行,两个事务就一定能成功commit提交。

快照读:select 

当前读:select * from xx for update; update ; delete;





免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

深入理解oracle的事务隔离性

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

SqlServer事务详解(事务隔离性和隔离级别详解) - 熊泽

概述  不少人对于事务的使用局限于begin transaction:开始事务、commit transaction:提交事务、rollback transaction:回滚事务的初步运用。并且知道使用事务后, 事务中所有操作命令必须作为一个整体提交或回滚,如
SqlServer事务详解(事务隔离性和隔离级别详解) - 熊泽
2019-10-07

深入解析数据库事务隔离级别:揭示数据一致性之谜

事务隔离级别是数据库系统中一个重要的概念,通过了解数据库事务隔离级别,可以更轻松地保证数据库数据的安全性与一致性。
深入解析数据库事务隔离级别:揭示数据一致性之谜
2024-02-25

深入解析数据库事务隔离级别:理解不同等级之间的差异

数据库事务隔离级别是控制并发事务如何访问和修改数据库的关键机制。通过了解不同隔离级别之间的差异,可以帮助您选择最适合应用程序需求的级别。
深入解析数据库事务隔离级别:理解不同等级之间的差异
2024-02-23

数据库事务隔离级别:深入剖析数据一致性的守护者

数据库事务隔离级别是数据库中一项重要的特性,它决定了数据库系统如何处理同时执行的事务。数据库中的事务,是指作为单个逻辑工作单元执行的一系列操作,通常包括读取和写入数据。事务隔离级别有助于确保数据库中的数据一致性和完整性。
数据库事务隔离级别:深入剖析数据一致性的守护者
2024-02-25

简单易懂理解事务的隔离级别

在讲事务的隔离级别,我们先得回忆一下事务的隔离性事务的隔离性是在当多个用户并发访问数据库时,比如说操作同一张表时,数据库为每一个用户开启事务,不能被其他事务的操作所干扰,多个并发事务之间需要相互隔离。即要达到这样的一种效果:对于任意的两个并发事务T1和T2,在
简单易懂理解事务的隔离级别
2017-04-06

事务隔离级别通俗指南:轻松理解不同隔离级别

事务隔离级别是数据库管理系统中控制并发事务访问共享数据的机制。它决定了哪些事务可以看到其他事务的更新,以及在不同的事务并发执行时会发生什么。了解事务隔离级别对任何系统架构师、数据库管理员和应用程序开发人员来说都是非常重要的,因为它可以帮助他们在设计和实现系统时避免并发问题。
事务隔离级别通俗指南:轻松理解不同隔离级别
2024-02-23

真正理解Mysql的四种事务隔离级别

什么是事务 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做。 事务的结束有两种,当事务中的所以步骤全部成功执行时,事务提交。如果
真正理解Mysql的四种事务隔离级别
2015-09-02

粗谈MySQL事务的特性和隔离级别

网上对于此类的文章已经十分饱和了,那还写的原因很简单——作为自己的理解笔记。前言​  此篇文章作为自己学习MySQL的一些个人理解,使用的引擎是InnoDb。首先先讲讲事务的概念,在《高性能MySQL》第三版中其对事务的描述是这样的:事务就是一组原子性的SQL
粗谈MySQL事务的特性和隔离级别
2014-10-16

深入挖掘数据库事务隔离级别:揭秘数据库一致性的奥秘

数据库事务隔离级别是数据库中一个重要的概念,它决定了在并发环境中事务的执行顺序和可见性,从而影响了数据库的一致性。本文深入探讨了数据库事务隔离级别,揭示了数据库一致性的奥秘。
深入挖掘数据库事务隔离级别:揭秘数据库一致性的奥秘
2024-02-10

聊聊MySQL事务的特性和隔离级别

网上对于此类的文章已经十分饱和了,那还写的原因很简单——作为自己的理解笔记。 前言 此篇文章作为自己学习MySQL的一些个人理解,使用的引擎是InnoDb。首先先讲讲事务的概念,在《高性能MySQL》第三版中其对事务的描述是这样的:事务就是
2022-05-11

编程热搜

目录