SQL必知必会
陈旸
清华大学计算机博士
立即订阅
10179 人已学习
课程目录
已完结 49 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词丨SQL可能是你掌握的最有用的技能
免费
第一章:SQL语法基础篇 (19讲)
01丨了解SQL:一门半衰期很长的语言
02丨DBMS的前世今生
03丨学会用数据库的方式思考SQL是如何执行的
04丨使用DDL创建数据库&数据表时需要注意什么?
05丨检索数据:你还在SELECT * 么?
06丨数据过滤:SQL数据过滤都有哪些方法?
07丨什么是SQL函数?为什么使用SQL函数可能会带来问题?
08丨什么是SQL的聚集函数,如何利用它们汇总表的数据?
09丨子查询:子查询的种类都有哪些,如何提高子查询的性能?
10丨常用的SQL标准有哪些,在SQL92中是如何使用连接的?
11丨SQL99是如何使用连接的,与SQL92的区别是什么?
12丨视图在SQL中的作用是什么,它是怎样工作的?
13丨什么是存储过程,在实际项目中用得多么?
14丨什么是事务处理,如何使用COMMIT和ROLLBACK进行操作?
15丨初识事务隔离:隔离的级别有哪些,它们都解决了哪些异常问题?
16丨游标:当我们需要逐条处理数据时,该怎么做?
17丨如何使用Python操作MySQL?
18丨SQLAlchemy:如何使用Python ORM框架来操作MySQL?
19丨基础篇总结:如何理解查询优化、通配符以及存储过程?
第二章:SQL性能优化篇 (18讲)
20丨当我们思考数据库调优的时候,都有哪些维度可以选择?
21丨范式设计:数据表的范式有哪些,3NF指的是什么?
22丨反范式设计:3NF有什么不足,为什么有时候需要反范式设计?
23丨索引的概览:用还是不用索引,这是一个问题
24丨索引的原理:我们为什么用B+树来做索引?
25丨Hash索引的底层原理是什么?
26丨索引的使用原则:如何通过索引让SQL查询效率最大化?
27丨从数据页的角度理解B+树查询
28丨从磁盘I/O的角度理解SQL查询的成本
29丨为什么没有理想的索引?
30丨锁:悲观锁和乐观锁是什么?
31丨为什么大部分RDBMS都会支持MVCC?
32丨查询优化器是如何工作的?
33丨如何使用性能分析工具定位SQL执行慢的原因?
34丨答疑篇:关于索引以及缓冲池的一些解惑
35丨数据库主从同步的作用是什么,如何解决数据不一致问题?
36丨数据库没有备份,没有使用Binlog的情况下,如何恢复数据?
37丨SQL注入:你的SQL是如何被注入的?
第三章:认识DBMS (7讲)
38丨如何在Excel中使用SQL语言?
39丨WebSQL:如何在H5中存储一个本地数据库?
40丨SQLite:为什么微信用SQLite存储聊天记录?
41丨初识Redis:Redis为什么会这么快?
42丨如何使用Redis来实现多用户抢票问题
43丨如何使用Redis搭建玩家排行榜?
44丨DBMS篇总结和答疑:用SQLite做词云
第四章:SQL项目实战 (3讲)
45丨数据清洗:如何使用SQL对数据进行清洗?
46丨数据集成:如何对各种数据库进行集成和转换?
47丨如何利用SQL对零售数据进行分析?
结束语 (1讲)
结束语 | 互联网的下半场是数据驱动的时代
SQL必知必会
登录|注册

15丨初识事务隔离:隔离的级别有哪些,它们都解决了哪些异常问题?

陈旸 2019-07-15
上一篇文章中,我们讲到了事务的四大特性 ACID,分别是原子性、一致性、隔离性和持久性,其中隔离性是事务的基本特性之一,它可以防止数据库在并发处理时出现数据不一致的情况。最严格的情况下,我们可以采用串行化的方式来执行每一个事务,这就意味着事务之间是相互独立的,不存在并发的情况。然而在实际生产环境下,考虑到随着用户量的增多,会存在大规模并发访问的情况,这就要求数据库有更高的吞吐能力,这个时候串行化的方式就无法满足数据库高并发访问的需求,我们还需要降低数据库的隔离标准,来换取事务之间的并发能力。
有时候我们需要牺牲一定的正确性来换取效率的提升,也就是说,我们需要通过设置不同的隔离等级,以便在正确性和效率之间进行平衡。同时,随着 RDBMS 种类和应用场景的增多,数据库的设计者需要统一对数据库隔离级别进行定义,说明这些隔离标准都解决了哪些问题。
我们今天主要讲解事务的异常以及隔离级别都有哪些,如果你已经对它们有所了解,可以跳过本次章节,当然你也可以通过今天的课程快速复习一遍:
事务并发处理可能存在的三种异常有哪些?什么是脏读、不可重复读和幻读?
针对可能存在的异常情况,四种事务隔离的级别分别是什么?
如何使用 MySQL 客户端来模拟脏读、不可重复读和幻读?
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《SQL必知必会》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(43)

  • 大牛凯 置顶
    老师好,对幻读有些迷惑,从网上看到幻读并不是说两次读取获取的结果集不同,幻读侧重的方面是某一次的 select 操作得到的结果所表征的数据状态无法支撑后续的业务操作。更为具体一些:select 某记录是否存在,结果显示不存在,准备插入此记录,但执行 insert 时发现此记录已存在,无法插入,此时就发生了幻读。

    作者回复: 你说的这种情况属于幻读。
    当你INSERT的时候,也需要隐式的读取,比如插入数据时需要读取有没有主键冲突,然后再决定是否能执行插入。如果这时发现已经有这个记录了,就没法插入。

    官方对幻读的定义是:The so-called phantom problem occurs within a transaction when the same query produces different sets of rows at different times.
    For example, if a SELECT is executed twice, but returns a row the second time that was not returned the first time, the row is a “phantom” row. (详见:
    https://dev.mysql.com/doc/refman/8.0/en/innodb-next-key-locking.html )

    需要说明下,不可重复读 VS 幻读的区别:
    不可重复读是同一条记录的内容被修改了,重点在于UPDATE或DELETE
    幻读是查询某一个范围的数据行变多了或者少了,重点在于INSERT

    所以,SELECT 显示不存在,但是INSERT的时候发现已存在,说明符合条件的数据行发生了变化,也就是幻读的情况,而不可重复读指的是同一条记录的内容被修改了。

    2019-07-15
    2
    40
  • 石维康
    老师可以详细讲解下脏读和幻读的区别吗?看文中的例子几乎是一样的。
    2019-07-15
    5
    18
  • mickey
    老师讲得有点问题。
    脏读针对的是数据的更新,而幻读针对的是多笔记录。
    第一天的例子实际上幻读。

    脏读:一个事务读取了另一个事务改写但还未提交的数据。
    幻读:一个事务读取了另一个事务插入的新纪录。
    不可重复读:在同一个事务中,多次读取同一数据返回的结果有所不同。
    2019-07-18
    11
  • flow
    关于事务隔离和异常问题的举例不够详细和严谨,具体可以看这个 https://www.liaoxuefeng.com/wiki/1177760294764384/1179611198786848

    以下是自己的理解:
    读未提交:在这个隔离级别下,事务A会读到事务B未提交的数据,在事务B回滚后,事务A读到的数据无意义,是脏数据,称为 脏读
    读已提交:在这个隔离级别下,只有在事务B已提交时,事务A才能读到,如果事务A先查询id为1的记录,之后事务B修改这条记录并提交,事务A再读取,两次结果会不一致,所以不可重复读。
    可重复读:在这个隔离级别下,就算事务B的修改已经提交,事务A读到的数据依旧是一致的。当事务B插入一条新数据并提交之后,事务A查询不到当前数据,查询不到就以为不存在,但是事务A却可以更新这条数据成功,并且更新后再次查询,数据出现了。一开始查询不到,但能修改,再次查询又出现了,跟幻觉一样,所以称为 幻读。
    2019-07-15
    1
    7
  • JackPn
    老师我感觉幻读也是不了重复读啊,都是一个事务过程中两次读到了另一个事务修改提交后的数据

    作者回复: 首先,不可重复读 和 幻读都是在先后两次读取的时候发现不一致的情况,但是两种读取略有差别:
    不可重复读是对于同一条记录内容的“不可重复读”
    幻读是对于某一范围的数据集,发现查询数据集的行数多了或者少了,从而出现的不一致。
    所以不可重复读的原因是 对于要查询的那条数据进行了UPDATE或DELETE
    而幻读是对于要查询的 那个范围的数据集,进行了INSERT。

    2019-07-15
    7
  • 一步
    老师示范的例子中,感觉脏读和幻读是一样的,都是读取了有可能不存在数据,区分不是很明确,老师能解答一下吗?
    2019-07-16
    4
  • 悟空
    湖人总冠军。。。
    2019-07-15
    2
    4
  • 一叶知秋
    两个问题个人理解是:
    1)四个级别分别是无限制(可以并发读写)、写事务加锁(可以并发读、读完立刻释放锁而不是等事务结束)、读写事务都加锁(可以并发读、读写都是事务结束才释放锁)、表锁(读写事务序列化执行、单线程执行)。 时间开销依次递增所以随着隔离等级递增并发性能会降低。
    2)区别在于不可重复读是由于其他事务的update、delete操作对数据进行了修改 重点在修改(内容修改)、幻读是其他事务由于delete、insert对表数据进行了修改重点在于数量新增、减少(数量变更)

    嘿嘿个人理解,不对希望指出 >o<
    2019-07-15
    4
  • L荀
    不可重复读,和幻读例子中事物不用提交么

    作者回复: 一个好问题,一般来说第二个事务需要进行提交。不过在文章中,我将客户端1的隔离级别设置为了 读未提交,因此不论客户端2是否提交,都会对客户端1造成影响。
    如果将客户端1的隔离级别设置为 读已提交,或者 可重复度。就需要对客户端2的事务进行提交,这时才会对客户端1在执行的事务产生影响。

    2019-07-15
    4
  • 啦啦啦
    打卡打卡
    2019-07-15
    3
  • mickey
    我的理解是:隔离性的保证靠锁,隔离级别越高越串行,并行度越低,性能越低。
    2019-07-18
    2
  • mickey
    transaction_isolation在MySQL 5.7.20中添加了作为别名 tx_isolation,现已弃用,并在MySQL 8.0中删除。可以改为:SHOW VARIABLES LIKE 'tx_isolation';
    2019-07-18
    2
  • dbtiger
    【隔离级别越高,就越影响系统的并发性能】
    1,首先隔离的实现机制是锁,隔离级别越高锁的代价越大(锁的粒度越小,表级锁到行级锁,共享锁到独占锁),终极为了一致性读写,只能是串行化操作读写(类似于操作系统的多进程原理,看着像是并行性执行,实则是单元分配CPU资源串行执行的过程)。
    【不可重复读和幻读的区别】
    2.我认为没啥区别,前者只是列值改变了,后者侧重是记录数变了。都是2次读的时候中间夹了一个已经执行了的事务,从而产生2次读的数据不一致的情况。

    另外,请教一下陈老师,存储过程里面有很多dml操作,每个dml语句加begin...end好,还是不加好,还是一样?两种状态对锁的持有时间是不是相同的?

    2019-07-15
    2
  • 0 error 0 warning 0 bug
    不可重复读和幻读还不是很理解,老师可以再详细讲讲吗

    作者回复: 不可重复读 VS 幻读的区别:
    不可重复读是同一条记录的内容被修改了,重点在于UPDATE或DELETE
    幻读是查询某一个范围的数据行变多了或者少了,重点在于INSERT

    2019-07-15
    2
  • xps
    老师,您只用了 READ UNCOMMITTED 级别演示了所有3种出现问题的种情况,但是我设置了READ COMMITTED 任然出现脏读,也就是本应该不出现问题的情况也出现问题?!看了评论好几个也是这个问题,请解释一下啊
    2019-08-10
    1
  • 未来的胡先森
    关于「隔离级别越高,就越影响系统的并发性能」我的思考:

    1、因为隔离级别越高就是越接近串行化操作(隔离级别最高的就是:可串行化)。而串行化操作就是按照事务的先后顺序,排队执行,一个事务操作可能就要等待很久才能执行,并发执行的效率就没有了。

    2、隔离就是给资源加锁,隔离级别越低,资源的共享程度就越高,大家都能去取自己需要的资源,而隔离级别高,共享程度越低,以至于一大份资源只能上一个用完了,下一个才能使用。就像免费开放的公园,没有收费的时候,想逛的时候随便哪条小路进去都行,收费了(加锁了),其他地方全拦住,一个人进去看好了,下一个再进去看。

    「不可重复读」和「幻读」的区别,老师已在留言区指出了。「不可重复读」就是针对于单独的某条数据同一事务前后读取不一致(被其他事务修改)。「幻读」针对于查询结果集的前后不一致,查询的数据表在事务的执行期间有执行插入删除的操作,导致查询结果的增加或减少。
    2019-08-09
    1
  • law
    大家有测试过吗,我测试了一下,mysql5.6在可重复读的级别下,还是会出现脏读和不可重复读啊。
    2019-07-25
    3
    1
  • Geek_1c165d
    我在客户端1和2都设置了SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED即读提交,然后我在客户端2开启事务,插入一条数据,不提交,然后去客户端1查询,发现可以查询到刚刚插入的未提交的数据。请问这是什么原因呢?
    2019-07-23
    2
    1
  • NO.9
    数据数量对应都异常:
    一条数据:脏读,不可重复读
    多条数据:幻读
    2019-07-16
    1
  • 柔软的胖
    根据ACID中持久性的特性,我理解,一个事务提交以后,另一个事务是可以看到这个提交内容的。
    在例子中,客户端2提交事务以后,客户端看到不同结果,应该是正确的。
    2019-07-16
    1
收起评论
43
返回
顶部