数据库事务的隔离级别相关概念

喜你入骨 提交于 2019-12-04 19:13:50

摘要

本文主要是重新理一下几个概念。经常发生一个对幻读错误的理解,比如场景:事务A 查询得到100条记录,事务B插入一条数据,事务B查询得到101条数据。很多人以为这是幻读场景,实际上不对,这属于不可重复读。MVCC机制就能解决这个问题。详见 Mysql中MVCC的使用及原理详解 这篇博客的示例。

幻读场景(假设id建立了唯一索引):比如 事务A查询id=1的数据,如果不存在,则插入id=1的这一行记录,在查询之后插入之前,事务B插入了id=1的记录,这时候事务A是查不到的,但是A是不能再插入id=1的数据行。

事务的ACID特性

原子性(A)

指处于同一个事务中的多条语句是不可分割的。要么就一起提交,要么就一起回滚,不存在部分提交,部分回滚。

一致性(C)

事务必须使数据库从一个一致性状态变换到另外一个一致性状态。比如转账,转账前两个账户余额之和为2k,转账之后也应该是2K。

隔离性(I)

指多线程环境下,一个线程中的事务不能被其他线程中的事务打扰

持久性(D)

事务一旦提交,就应该被永久保存起来。

事务的隔离级别概念

RU(Read uncommitted 未提交读)

事务A能读取到事务B中未提交的数据。

存在脏读,不可重复读,幻读的问题。

RC(Read committed 已提交读)

事务A能读取到事务B中已提交的数据。

解决脏读的问题,存在不可重复读,幻读的问题。

RR(REPEATABLE READ 可重复读)

同一个事务中,事务内部没有做更新的前提下,多次读出来的数据应该是一样的,不受别的事务操作影响。这里只解决脏读、不可重复读、不要求解决幻读。也就是说同一个事务中多次读出来的数据必须是一致的,但是,范围查询出来的条数可能不相等。

解决脏读,不可重复读的问题,存在幻读的问题,默认隔离级别,使用 MMVC机制 实现可重复读。

mysql 默认就是这个隔离级别. 这这种隔离级别实现的方法就是 MVCC,Mysql中MVCC的使用及原理详解

Serializable (可串行化)

锁表,所有的操作都是串行的,这样就不存在脏读、幻读、不可重复读。

不同的隔离级别可能会导致的现象概念

脏读

一个事务中读取到了另一个事务未提交的数据。这个好理解。

幻读

幻读,并不是说两次读取获取的结果集不同,幻读侧重的方面是某一次的 select 操作得到的结果所表征的数据状态无法支撑后续的业务操作。更为具体一些:select 某记录是否存在,不存在,准备插入此记录,但执行 insert 时发现此记录已存在,无法插入,此时就发生了幻读。

解决这种问题的方法,就是加RangeS(范围锁)。

这里有个常见错误理解的场景:事务A查询全表有多少条数据,第一次查出来 100条,另一个事务B插入一条数据,这时候事务A再去查,查出来有101条数据。很多人以为这是幻读,实际上这不是。在RR隔离级别验证过,查出来的任然之后100条数据。

不可重复读

一个事务中读取到另一个事务中update的数据。这种的场景:事务A读取id=1对应的value=1,事务B这时候将id=1的value改成了2,事务A再去读,读到了id=1的value变成了2,也就是同一个事务里面两次读,读出来的结果不一致。

不同的事务隔离级别可能会到导致哪些现象的关系图

参考文档

MySQL脏读、不可重复读、幻读 (这里幻读理解错误)

mysql 幻读的详解、实例及解决办法

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!