三、MySQL事务

三、MySQL事务

1. 事务有哪些特性?

事务是由MySQL的引擎来实现的,常见的InnoDB引擎是支持事务的

事务必须遵守4个特性(ACID),分别如下:

  • 原子性(Atomicity):一个事务中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。而且事务执行过程中发生错误,会被回滚到事务开始前的状态,就像这个事务从来没被执行过一样。
  • 一致性(Consistency):是指事务操作前和操作后,数据满足完整性约束,数据库保持一致性状态。举例子来说,比如A和B分别有800和600块钱,A给B转账200元,那么实际上A要扣除200块,B要增加200块。一致性就是要求上述步骤操作后,最后的结果是用户A还有600元,用户B有800元,总共还是1400元
  • 隔离性(Isolation):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时候,由于交叉执行而导致的数据不一致。每个事务都有一个完整的数据空间,对其他并发事务是隔离的
  • 持续性(Durability):事务处理结束后,对数据修改就是永久的,即使系统故障也不会丢失

原子性——undo log(回滚日志)来保证

一致性——持久+原子+隔离来保证

隔离性——MVCC多版本并发控制,或者锁机制来保证

持久性——redo log(重做日志)来保证

2. 并行事务会有什么问题

MySQL服务端是允许多个客户端连接的,这意味着MySQL会出现同时处理多个事务的情况

同时处理多个事务的时候,可能会出现:脏读(dirty read)、不可重复读(non-repeatable read)、幻读(phantom read)

2.1 脏读

如果一个事务「读到」了另一个「未提交事务修改过的数据」,就意味着发生了脏读的现象

假设A和B这两个事务同时在处理,事务A先开始从数据库中读到余额数据,然后再执行更新操作,如果此时事务A还没有提交事务,而此时事务B也从数据库中读余额,那么事务B读的数据是事务A刚刚更新后的数据,即使事务A还没有提交

image-20221208214124867

如果事务A还没有提交事务,那么随时可能发生回滚曹邹

如果上面这种情况,事务A发生了回滚,那么事务B刚才得到的数据就是过期的数据,这种现象被称为脏读

2.2 不可重复读

在一个事务内多次读取同一个数据,如果出现前后两次读取到的数据不一样的情况,就意味着发生了「不可重复读」现象

举例子来说,假设A和B两个事物在同事处理,事务A开始先从数据库读取余额数据,然后继续执行代码逻辑处理,在这过程中如果事务B更新了这条数据并提交事务,那么当事务A再次读取该数据的时候,就会发现前后两次读到的数据是不一致的,这种现象就被称为不可重复读

image-20221208214638986

2.3 幻读

在一个事务内多次查询每个符合条件的「记录数量」,如果出现了前后两次查到的记录数量不一样的情况,就意味着发生了「幻读」现象

假设有A和B这两个事务同时在处理,事务A开始先从数据库查询账户余额大于100万的记录,发现共有5条,然后事务B也按照相同的搜索条件,也是查出了5条记录

image-20221208215416955

接下来,事务A插入了一条余额超过100万的账户,并提交了事务,此时数据量变为6条

然后事务B再次查询账户余额大于100万的记录,此时查询到的记录数量有6条,发现和前一次读到的记录数量不一致了,就感觉发生了幻觉一样,这种现象被称为幻读

3. 事务的隔离级别有哪些?

当多个事务并发的时候,会有脏读、不可重复读、幻读的现象,这些现象会对事务的一致性产生不同的影响

  • 脏读:读到其他事物未提交的数据
  • 不可重复读:同一个事务下,前后读取的数据不一致
  • 幻读:同一个事务下,前后读取的数据量不一致

这三个现象的严重性排序如下:

image-20221208215812961

SQL标准提出了四种隔离级别,来规避这些现象,隔离级别越高,性能效率就越低,这四个隔离级别如下:

  • 串行化(serializable):会对记录加上读写锁,在多个事务对这条记录进行读写操作的时候,如果发生了读写冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行;
  • 可重复读(repeatable read):指一个事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的(mysql innodb引擎默认的隔离级别)
  • 读已提交(read committed):指一个事务提交之后,他做的变更才能被其他事务看到
  • 读未提交(read uncommitted):指一个事务还没提交的时候,他做的变更就能被其他事务看到

按隔离水平高低排序如下:

image-20221208220734571

针对不同的隔离级别,并发事务时可能发生的现象也不同

image-20221208220812315


三、MySQL事务
http://example.com/2022/12/08/develop/mysql/三、MySQL事务/
作者
Curious;
发布于
2022年12月8日
许可协议