mysql -- 事务(脏读、不可重复读、幻读)

一、概念

事务就是把一组操作打包在一起,执行的时候使这些操作之间满足一定的特性,避免出现问题。

例:
如果 A 向 B 发 200 红包,此时 A 的余额减少 500 元,若 B 收了红包之后余额并没有增加 500 元,则说明 发红包、收红包 这一组操作出现了错误。

事务就是防止中间出现错误,因此事务应该具备以下特征:

  1. 原子性(一个事务是一个不可分割的工作单位)
  2. 一致性(数据在事务执行前后没有错误)
  3. 持久性(事务执行之后,数据被持续修改)
  4. 隔离性(多个事务并发执行时,事务之间不能互相干扰)
    ps : 隔离性 和 并发 是相矛盾的。
    隔离保证了数据的准确性;
    并发保证了事务执行的效率。
    如果多个事务之间隔离性越强,并发程度就越低,效率就越低;
    如果多个事务之间隔离性越弱,并发程度就越高,效率也就越高。

二、事务并发执行时产生的问题

  1. 脏读
    事务 A 正在修改数据,事务 B 已经读取了事务 A 的数据。(事务 A 随时可能再次修改数据)
    解决办法:引入写加锁
    给写操作加锁:A 在修改数据时,B 不能读取数据(阻塞),直到事务 A 将数据提交(写解锁)后才能读取。
    引入写加锁,并发程度越低,效率也就越低,隔离性就高了。
  2. 不可重复读
    事务 B 多次读取事务 A,但读取到的数据不同(数据 B 读取数据时,事务 A 仍可更改数据)。
    解决办法:
    在写加锁的基础上,引入读加锁。
    读加锁:在事务 B 读取数据时,事务 A 也不能修改数据。
    直到读完(读解锁)之后,才能再次修改。
    引入读加锁,并发程度更低,效率也更低,隔离性就更高了。
  3. 幻读
    事务 B 多次读取事务 A,发现读取的结果集不同(A 不可修改原本数据,但可新增或删减数据)
    例如:发布文章,A 虽不可修改原有文章,但可以发表新文章,或删除原有文章。
    解决办法:
    使事务执行完全串行化。
    此时,并发程度最低,效率也最低,隔离性最高。

三、mysql 的隔离级别

  1. read uncommitted:允许读取未提交的数据(隔离程度最低,会有脏读问题)
  2. read committed:只允许读取已提交的数据,相当于引入了写加锁(解决了脏读,但是有不可重复问题)
  3. repeatable read(MySQL 的默认隔离级别):引入写加锁和读加锁(解决了不可重复读,但是会有幻读问题)
  4. serializable:串行化执行(隔离程度最高,并发程度最低,解决了幻读问题)
©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页