[[Mysql学习]]

1.Mysql事务

[!note] 什么是事务
一个最小的不可再分割的工作单元, 通常一个事务对应一个完整的业务, 一个完整的业务需要批量的DML(insert, update, delete)共同完成。

1.1 事务的基本要素(ACID)

  1. 原子性(A)
    整个数据库事务是不可分割的工作单元,只有使事务中所有的数据库操作都执行成功,才算整个事务成功。如果事务中任何一个SQL语句执行失败, 已经执行成功的SQL语句也必须撤销, 数据库状态应该退回到执行事务前的状态。
  2. 一致性(C)
    可以理解为事务对数据完整性的遵循。这些约束可能包括主键约束, 外键约束,或者用户自定义的约束。事务执行的前后都是合法的数据状态,不会违背任何的数据完整性。
  3. 隔离性(I)
    隔离性还有其他称呼, 如并发控制, 可串行化, 锁等, 事务的隔离性要求每个读写事务的对象对其他事务的操作对象能相互隔离, 即该事务的提交对其他事务都不可见。
  4. 持久性(D)
    持久性好理解, 就是事务一旦提交, 其结果就是永久性的,即使发生宕机等故障,数据库也能将数据恢复, 需要注意的是, 只能从事务本身的角度来保证结果的永久性。

1.2 事务的实现

事务的隔离性由锁来实现。原子性, 一致性, 隔离性则是通过数据库的redo logundo log来实现。redo log称为重做日志, 用来保证事务的原子性和持久性, undo log用来保证事务的一致性。

2.事务隔离

2.1 隔离级别

事务隔离级别脏读不可重复读幻读
读未提交(read-uncommited)
读已提交(read-commited)
可重复读(repeatable-read)有(Mysql中间隙锁可解决)
串行化(serializable)

2.2 级别定义

  1. 读未提交(read-uncommited)
    所有事务都可以看到其他未提交事务的执行结果,本隔离级别很少用到实际应用场景,因为他的性能不比其他级别好多少。
  2. 读已提交(read-commited)
    这是大多数数据库默认的事务隔离级别(<mark style="background: #FFB86CA6;">但不是Mysql默认的</mark>),他满足了隔离的简单定义:一个事务只能看见已经提交事务所作的改变。
  3. 可重复读(repeatable-read)
    Mysql默认的事务隔离级别。它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上, 导致另一个棘手的问题,[[#2.3.3 幻读(phantom read)|幻读]].
    <mark style="background: #BBFABBA6;">InnoDB存储引擎,通过多版本并发控制(MVCC)机制解决了该问题。</mark>
  4. 串行化(serializable)
    最高的事务隔离级别, 通过强制事务排序, 使之不可能相互冲突, 从而解决幻读问题。简言之, 它是在每个读的数据行上加上共享锁 ,在这个级别,可能导致大量的超时现象和锁竞争。

    2.3 脏读,不可重复读, 幻读

站外链接 → 脏读、不可重复读、幻读

2.3.1 脏读(dirty read)

脏读是指事务读取到其他事务未提交的数据。

2.3.2 不可重复读(non-repeatable read)

不可重复读是指在同一次事务中前后查询不一致的问题。重点强调是<mark style="background: #FF5582A6;">同一事务</mark>。

2.3.3 幻读(phantom read)

幻读是在一次事务中前后数据量发生变化,用户产生不可预料的问题。
分为并发插入和并发删除的情况:

  1. 并发插入
    A先执行查询, 假设当前有一条数据, 然后B又插入了一条数据,当A再次查询的时候, 发现多了1条数据, 像出现幻觉一样.
  2. 并发删除
    并发删除的道理和并发插入是一样的

2.4 不可重复读与幻读的区别

  1. 不可重复读和幻读都是读取了另一条已经提交了的事务(区别于脏读), 不同的是: 不可重复读查询的都是同一个数据项, 而幻读针对的是同一批数据项.
  2. 不可重复读重点是修改, 而幻读重点是插入或删除.
  3. 如果从控制的角度来看, 两者的区别较大

    1. 对于前者, 只需要锁住满足条件的的记录
    2. 对于后者, 要锁住满足条件及其相近记录

3.总结

  1. 脏读是指事务读取其他事务正在处理的未提交数据
  2. 不可重复度指在并发更新时 , 另一个事务前后执行相同条件的查询得到的数据不一致
  3. 幻读指并发插入, 并发删除时, 另一个事务前后执行相同条件的查询得到的数据不一致

    4.我的话

Mysql事务隔离级别的名字是针对脏读, 不可重复读, 幻读情况的区分, 也是情况的高度总结.

5.记忆宫殿助记

Pasted image 20231128110940.png

从前, Mysql事务国王有4个儿子, 老大叫读未提交, 老二叫读已提交, 老三叫可重复读, 老四叫串行化.

老大身体非常弱, 治不好脏读, 不可重复读, 幻读的病, 病的很严重.
老二身体好一点, 治好了脏读, 但是不可重复读和幻读的毛病还是挺严重.
老三比较幸运, Mysql事务非常心疼他, 他自己身体也好, 治好了脏读和不可重复读, 但是幻读不好治, 在老爹的特殊关照下, 吃了几服MVCC的药, 也治好了.
老四的身体太特殊了, 住在实验室里头, 虽然身体没毛病, 但是实验室门禁很严格, 进出都花不少时间.

老大身体太弱, 老四控制的太严, 都不让他俩跟别人玩. 只有老二, 老三可以出去玩, 特别是老三是佼佼者.


白石神君
1 声望0 粉丝

技术老白, 你值得信赖