分析事务的隔离级别

  在DBMS中,事务保证了一个操作序列可以全部执行或者全部不执行(原子性),从一个状态撞边到另外一个状态(一致性)。由于事务满足持久性。所以一旦事务被提交之后,数据就能被持久化下来,又因为事务是满足隔离性的,所以,当多个事务同时处理同一个数据的时候,多个事务是互不影响的。所以,在多个事务并发操作的过程中,如果控制不好隔离级别,就可能产生脏读,不可重复读或者幻读等现象

  在数据库事务的ACID四个属性中,隔离性是最放松的一个。可以在数据操作过程中利用数据库的锁机制或者多版本并发控制机制获取更高的隔离等级。但是,随着数据库隔离级别的提高,数据的并发能力也有所下降。所以,如何在并发性和隔离性之间做一个很好的权衡就成了一个直观重要的问题。

  在软件开发中,几乎每类这样的问题都会有多种最佳实践来供参考,很多DBMS定义了多个不同的“事务隔离等级”来控制锁的成都和并发能力。

  ANSI/ISO SOL定义的标准隔离级别有四种,从高到底依次为:可序列化、可重复读、提交读、未提交读。

  1、未提交读:最低的隔离级别。在这种事务隔离级别下,一个事务可以读到另外一个事务未提交的数据

  

  实现原理:事务在读数据的时候并未对数据加锁,事务在修改数据的时候支队数据增加行级共享锁

  

  现象:事务1读取某行记录时,事务2也能对这行记录进行读取、更新(因为事务1并未对数据增加任何锁)

  当事务2对该记录进行更新时,事务1再次读取该记录,能读到事务2对该记录的修改版本(因为事务二只增加了共享读锁,事务1可以再增加共享读锁读取数据),即使该修改尚未被提交

  事务1更新某行记录时,事务2不能对这行记录做更新,知道事务1结束。(因为事务1对数据增加了共享读锁,事务2不能增加排他写锁进行数据的修改)

  

  2、提交读:在一个事务修改数据过程中,如果事务还没提交,其他事务不能读取该数据

  数据库锁的情况:

    1、事务对当前被读取的数据加行级共享锁(当读到时才加锁),一旦读完该行,立即释放该行级共享锁

    2、事务在更新某数据的瞬间(就是发生更新的瞬间),必须先对其加行级排他锁,直到事务结束才释放

  现象:

    1、事务1在读取某行记录的整个过程中,事务2都可以对该行记录进行读取(因为事务1对该行记录增加行级共享锁的情况下,事务2同样可以对该数据增加共享锁来读数据)

    2、事务1读取某行的一瞬间,事务2不能修改该行数据,但是,只要事务1读取完该行数据,事务2就可以对该行数据进行修改。(事务1在读取的一瞬间会对数据增加共享锁,任何其他事务都不能对该行数据增加排他锁。但是事务1只要读完该行数据,就会释放行级共享锁,一旦锁释放,事务2就可以对数据增加排他锁并修改数据)

    3、事务1更新某行记录时,事务2不能对这行记录做更新,直到事务1救赎。(事务1在更新数据的时候,会对该行数据增加排他锁,直到事务结束才会释放锁,所以,在事务2没有提交之前,事务1都不能对数据增加共享锁进行数据的读取。所以,提交读可以解决脏读的现象)

  

  可重复读:由于提交读隔离级别会产生不可重复读的读现象。所以,比提交读更高一个级别的隔离级别就可以解决不可重复读的问题。这种隔离级别就叫可重复读

  数据库锁情况:

    1、事务在读取某数据的瞬间(就是开始读取的瞬间),必须先对其加行级共享锁,直到事务结束才释放

    2、事务在更新某数据的瞬间(就是发生更新的瞬间),必须先对其加行级排他锁,直到事务结束才释放

  现象:

    1、事务1在读取某行记录的整个过程中,事务2都可以对该行记录进行读取(因为事务1对该行记录增加行级共享锁的的情况下,事务2同样可以对该数据增加共享锁来读数据)

    2、事务1在读取某行记录的整个过程中,事务2都不能修改该行数据(事务1在读取的整个过程会对数据增加共享锁,直到事务提交才会释放锁。所以整个过程中,热河其他事务都不能对该行数据增加排他锁。所以,可重复读能够解决不可重复读的现象)

    3、事务1更新某行记录时,事务2不能对这行记录做更新,直到事务1结束。(事务一在更新数据的时候,会对该行数据增加排他锁,知道事务结束才会释放锁,所以,在事务二没有提交之前,事务一都能不对数据增加共享锁进行数据的读取。所以,提交读可以解决脏读的现象)

  可序列化 

  可序列化(Serializable)是最高的隔离级别,前面提到的所有的隔离级别都无法解决的幻读,在可序列化的隔离级别中可以解决。我们说过,产生幻读的原因是事务一在进行范围查询的时候没有增加范围锁(range-locks:给SELECT 的查询中使用一个“WHERE”子句描述范围加锁),所以导致幻读。

  数据库锁情况   

  1、事务在读取数据时,必须先对其加 表级共享锁 ,直到事务结束才释放;

  2、事务在更新数据时,必须先对其加 表级排他锁 ,直到事务结束才释放。

  现象:

  1、事务1正在读取A表中的记录时,则事务2也能读取A表,但不能对A表做更新、新增、删除,直到事务1结束。(因为事务一对表增加了表级共享锁,其他事务只能增加共享锁读取数据,不能进行其他任何操作)

  2、事务1正在更新A表中的记录时,则事务2不能读取A表的任意记录,更不可能对A表做更新、新增、删除,直到事务1结束。(事务一对表增加了表级排他锁,其他事务不能对表增加共享锁或排他锁,也就无法进行任何操作)

虽然可序列化解决了脏读、不可重复读、幻读等读现象。但是序列化事务会产生以下效果:

  1.无法读取其它事务已修改但未提交的记录。

  2.在当前事务完成之前,其它事务不能修改目前事务已读取的记录。

  3.在当前事务完成之前,其它事务所插入的新记录,其索引键值不能在当前事务的任何语句所读取的索引键范围中

原文地址:https://www.cnblogs.com/alighie/p/8297150.html

时间: 2024-10-10 04:26:03

分析事务的隔离级别的相关文章

实战分析:事务的隔离级别和传播属性

什么是事务? 要么全部都要执行,要么就都不执行. 事务所具有的四种特性 原子性,一致性,隔离性,持久性 原子性 个人理解,就是事务执行不可分割,要么全部完成,要么全部拉倒不干. 一致性 关于一致性这个概念我们来举个例子说明吧,假设张三给李四转了100元,那么需要先从张三那边扣除100,然后李四那边增加100,这个转账的过程对于其他事务而言是无法看到的,这种状态始终都在保持一致,这个过程我们称之为一致性. 隔离性 并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据是独立的: 持

数据库事务【隔离级别】

为了快速同步数据的需要,我分段执行了两次python脚本,即开启了两个进程同步数据,结果服务器不时报出数据库死锁异常,通过排查代码和数据库日志发现,是由长事务并发引起的.代码中有入账和出账两个方法,里面涉及操作较多,都为其加了事务,抛出异常时可自动回滚,采用数据库(mysql)默认的隔离级别(Repeatable read).提到并发,一般就会想到用同步代码块的方法的处理,但是由于项目是分布式的,共用一个主库,单单在代码加锁是不能保证数据的准确的,那就只能在数据库层面去考虑加锁了.由于数据量暂时

MySQL数据库事务各隔离级别加锁情况--read uncommitted篇(转)

本文转自https://m.imooc.com/article/details?article_id=17291,感谢作者 1.目的 1.1 合适人群 1.数据库事务特征我只是背过,并没有很深刻的理解. 2.数据库事务的隔离级别只是了解,并没有深刻理解,也没有在实际工作中体验使用过. 3.经常面试被人问起数据库加锁情况,一头雾水,很懵. 4.在网上找过很多博客,有的写得太多没耐心看,有的写得摘抄的定义,泛泛而谈,没有实操更没有讲解. 1.2 关于这篇分享对以上问题的解决 1.实践出真知,如果认真

MySQL数据库事务各隔离级别加锁情况--read committed && MVCC(转)

本文转自https://m.imooc.com/article/details?article_id=17290 感谢作者 上篇记录了我对MySQL 事务 隔离级别read uncommitted的理解.这篇记录我对 MySQL 事务隔离级别 read committed & MVCC 的理解. 前言 可以很负责人的跟大家说,MySQL 中的此隔离级别不单单是通过加锁实现的,实际上还有repeatable read 隔离级别,其实这两个隔离级别效果的实现还需要一个辅助,这个辅助就是MVCC-多版

事务、事务的四大特性(ACID)、三大并发问题、四种锁、事务的隔离级别

一.什么是事务? 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消.也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做. 事务的结果有两种:当事务中的所有步骤全部成功执行完成时,事务提交.如果其中一个步骤失败,将发生回滚操作,撤消之前到事务开始时的所有操作. 二.事务的四个特性 事务具有四个特征:原子性( Atomicity ).一致性( Consistency ).隔离性( Isolation )和持续性( Durabil

数据库事务的隔离级别

数据库事务的隔离级别有4个,由低到高依次为Read uncommitted.Read committed.Repeatable read.Serializable,这四个级别可以逐个解决脏读.不可重复读.幻读这几类问题. √: 可能出现    ×: 不会出现   脏读 不可重复读 幻读 Read uncommitted √ √ √ Read committed × √ √ Repeatable read × × √ Serializable × × × 注意:我们讨论隔离级别的场景,主要是在多个

事务的特性及事务的隔离级别(转)

原文:http://www.cnblogs.com/fjdingsd/p/5273008.html 本篇讲诉数据库中事务的四大特性(ACID),并且将会详细地说明事务的隔离级别. 如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下四个特性: ⑴ 原子性(Atomicity) 原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,这和前面两篇博客介绍事务的功能是一样的概念,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响. ⑵ 一致性(Consi

事务的隔离级别及mysql对应操作

/* 本次高并发解决之道 1,更改事务隔离级别为 read uncommitted读未提交 2,查询前设定延迟,延迟时间为随机 50-500 微秒 3,修改数据前将 超范围作为 限定修改条件 事务是作为单个逻辑工作单元执行的一系列操作.可以是一条SQL语句也可以是多条SQL语句.一个支持事务 Transaction的数据库系统,必需要具有这四种特性,以保证保证数据的正确性 事务的隔离级别 隔离级别与并发性是互为矛盾的:隔离程度越高,数据库的并发性越差:隔离程度越低,数据库的并发性越好. 隔离级别

事务的隔离级别和传播行为

一.事务的隔离级别 1.五种事务的隔离级别 ①读_未提交(read_uncommitted): 会出现脏读.不可重复读.幻读.(隔离级别最低,并发性能高) ②读_已提交(read_committed):会出现不可重复读.幻读.(锁定正在读取的行) ③重复读(repeatable_read):会出现幻读.(锁定所读取的所有行) ④序列化(serializable):保证所有的情况不会发生:(锁表) ⑤默认的隔离级别: 大多数的默认隔离级别是:读已提交(read_commited)如:Sql Ser