各种非正常读

脏读

事务A读取到了事务B还未提交的数据,被称之为脏读。

【MySQL篇】MySQL的MVCC是什么‍,解说清楚什么是脏读、不行重复读、幻读

不行重复读

在并发更新操作时,在同一次事务中,前后两次查询到的数据是不一样的。

【MySQL篇】MySQL的MVCC是什么‍,解说清楚什么是脏读、不行重复读、幻读

幻读

在并发新增、修改时,在同一次事务中,前后两次查询到的数据量不一致。用户发生不行意料的问题

【MySQL篇】MySQL的MVCC是什么‍,解说清楚什么是脏读、不行重复读、幻读


事务阻隔等级

能够处理脏读、幻读、不行重复读的问题。

阻隔等级 阻隔等级英文 脏读 幻读 不行重复读 加锁读 阐明
读未提交 Read UnCommitted (RU) 能够读取到其它事物未提交的内容
读已提交 Read Committed (RC) 只能读取到其它事物提交成功的内容
可重复读 Repeatable Read (RR) innoDB在外 读取某行后,不允许其它事物操作此行,直到事物结束
序列化 Serializable 等候其它事物执行完成后,依次执行,性能低,安全性高

MVCC并发版别操控

MVCC全称(Multiversion Concurrency Control)

在MySQL的InnoDB引擎下,RC、RR根据MVCC(多版别并发操控)进行并发事务操控,MVCC是根据数据版别来进行并发事务拜访的一种技能。

RR在MVCC下不能确保不发生幻读的问题。由于假如在两次快照读中心交叉了当时读,那么ReadView会被重新生成,因此或许会导致幻读的问题发生。既第一次读到了3条数据,第二次读到了2条数据。

【MySQL篇】MySQL的MVCC是什么‍,解说清楚什么是脏读、不行重复读、幻读

UNDO_LOG

UNDO_LOG(回滚日志)版别链条

【MySQL篇】MySQL的MVCC是什么‍,解说清楚什么是脏读、不行重复读、幻读

MySQL会在确定UNDO_LOG没有其它事务引用时才会删去。

ReadView

ReadView就是快照读SQL执行时,MVCC提取数据的依据。当时读不会运用MVCC。

  • 快照读:就是最根底的查询句子。运用MVCC。
  • 当时读:执行下列句子时读取数据的方法。运用行锁 间隙锁。
    • INSERT、UPDATE、DELETE
    • SELECT … FOR UPDATE
    • SELECT … LOCL IN SHARE MODE

ReadView属性

  • m_ids:当时活泼的事务id列表
    • 活泼:没有commit、rollback的事务
  • min_trx_id:最小活泼的事务id
  • max_trx_id:预分配的事务id,最大事务编号 1
  • cerator_trx_id:ReadView创建者的事务编号

ReadView生成机遇:

  • 读已提交RC:每次读取都会生成新的ReadView
    • 【MySQL篇】MySQL的MVCC是什么‍,解说清楚什么是脏读、不行重复读、幻读
  • 可重复读RR:会复用第一次生成的ReadView
    • 由于所运用的ReadView是一模一样的,所以RR是可重复读的。
    • 【MySQL篇】MySQL的MVCC是什么‍,解说清楚什么是脏读、不行重复读、幻读

ReadView提取数据的逻辑

ReadView会根据自己的属性,去到UNDO_LOG中提取数据,提取的顺序由UNDO_LOG的事务号从大到小依次读取,假如当时不满足,就会往下接着找,最终找到符合条件的数据。规则如下。

  • 判别当时事务id是否等于,ReadView创建者的事务id,假如是的话就阐明这个事务是自己的,能够拜访数据。
  • 判别trx_id < min_trx_id,自己的事务id是否小于最小的活泼事务id,假如是的话阐明自己现已被提交了,能够拜访。
  • 判别 trx_id > max_trx_id 假如自己的事务id大于ReadView生成时的最大事务ID,那么阐明自己还没有提交。不行以拜访。
  • 判别 min_trx_id <= trx_id <= max_trx_id,假如当时事务id大于等于最小事务id,并且小于等于预分配事务id,建立的话就去活泼的事务id列表中查找,没找到,阐明自己被提交了,那就能够拜访,不然就不行以拜访。

【MySQL篇】MySQL的MVCC是什么‍,解说清楚什么是脏读、不行重复读、幻读

参阅地址:IT老齐


Spring事务

三方操作怎么确保原子性

在开发事务的过程中,往往或许遇到这种场景,在数据库事务操作完毕后,给第三方组件、服务发送一条音讯、HTTP恳求。像这种操作假如直接写在事务内部,则有或许会影响主要事务代码的运转,假如写在外部,则无法确保事务操作与三方操作的原子性。

在Spring中供给了一个功用,事务回调接口