MySQL事务隔离级别

  事务有 ACID 四个基本属性:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)

  1. 事务就是要保证一组数据库操作,要么全部成功,要么全部失败;
  2. 在 MySQL 中,事务支持是在引擎层实现的;
  3. 并不是所有引擎都支持事务,如 MyISAM 就不支持,InnoDB 就支持;

脏读

  脏读(dirty read),简单来说,就是一个事务在处理过程中读取了另外一个事务未提交的数据。这种未提交的数据我们称之为脏数据。依据脏数据所做的操作肯能是不正确的。

不可重复读

  不可重复读(non-repeatable read),是指一个事务范围内,多次查询某个数据,却得到不同的结果在第一个事务中的两次读取数据之间,由于第二个事务的修改,第一个事务两次读到的数据可能就是不一样的。

  脏读和不可重复读的区别:脏读是某一事务读取了另外一个事务未提交的数据,不可重复读是读取了其他事务提交的数据。

幻读

  幻读(phantom read),是事务非独立执行时发生的一种现象。

  例如事务 T1 对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务 T2 又对这个表中插入了一行数据项为“1”的数据,并且提交给数据库。而操作事务 T1 的用户如果再查看刚刚修改的数据发现还有1。

  幻读和不可重复读:幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。

事务的隔离级别

Serializable(串行化)

  花费最高代价但最可靠的事务隔离级别。读写都加锁。事务 100% 隔离,可避免脏读、不可重复读、幻读的发生。

 Repeatable read(可重复读,默认级别)

  多次读取同一范围的数据会返回第一次查询的快照,即使其他事务对该数据做了更新修改。事务在执行期间看到的数据前后必须是一致的。

  但如果这个事务在读取某个范围内的记录时,其他事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行,这就是幻读。

  可避免脏读、不可重复读的发生。但是可能会出现幻读

Read committed (读已提交)

  保证一个事物提交后才能被另外一个事务读取。另外一个事务不能读取该事物未提交的数据。可避免脏读的发生,但是可能会造成不可重复读。

Read uncommitted (读未提交)

  最低的事务隔离级别,一个事务还没提交时,它做的变更就能被别的事务看到。

  事务隔离级别越高,越能保证数据的完整性和一致性,但是付出的代价却是并发执行效率的低下。

隔离级别的实现

  事务的机制是通过视图(read-view)来实现的并发版本控制(MVCC),不同的事务隔离级别创建读视图的时间点不同。

  1. 可重复读是每个事务重建读视图,整个事务存在期间都用这个视图。

  2. 读已提交是每条 SQL 创建读视图,在每个 SQL 语句开始执行的时候创建的。隔离作用域仅限该条 SQL 语句。

  3. 读未提交是不创建,直接返回记录上的最新值

  4. 串行化隔离级别下直接用加锁的方式来避免并行访问。

  这里的视图可以理解为数据副本,每次创建视图时,将当前已持久化的数据创建副本,后续直接从副本读取,从而达到数据隔离效果。

  我们每一次的修改操作,并不是直接对行数据进行操作。

posted on 2019-11-12 22:26  tianzeng  阅读(220)  评论(0编辑  收藏  举报

导航