事务ACID

原子性

A6FB256E-862A-417F-906B-F30461BC55F9.png
《MySQL技术内幕》7.1.2

一致性

0EACAA77-DE48-49F5-BED2-6027EFBC9683.png
《MySQL技术内幕》7.1.2

持久性

13273D41-743A-4FC5-B06F-C65BC54A096B.png
《MySQL技术内幕》7.1.2

隔离性

E553C2AE-16F7-4C37-B411-7BCB82FD961E.png
《MySQL技术内幕》7.1.2


事务实现

事务隔离性由第6章讲述的锁来实现。原子性、一致性、持久性通过数据库的redolog和undo log来完成。redo log称为重做日志,用来保证事务的原子性和持久性。undo log用来保证事务的一致性。
《MySQL技术内幕》7.2

原子性、一致性、持久性实现

参考

[

](https://www.processon.com/view/link/61d052c8e0b34d1be79b532d)


隔离性实现


当多个事务操作数据库数据时,就会存在一系列并发问题:[2,5]
数据丢失
脏读:读到了其他事务未提交的数据 (在ru下会出现)
不可重复读
幻读;
image.png

需要通过事务隔离机制来解决:
读未提交:一个事务还没提交时,它做的变更就能被别的事务看到
读已提交:一个事务提交之后,它做的变更才会被其他事务看到
可重复读:一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。
串行化:对于同一行记录,“写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。

|

脏读 不可重复读 幻读
READ-UNCOMMITTED
READ-COMMITTED ×
REPEATABLE-READ × ×
SERIALIZABLE × × ×

(在InnoDB中,在REPEATABLE-READ中使用Next-Key Lock)

而事务隔离可以通过锁机制来实现的。

共享锁(S)和排他锁(X)。共享锁允许一个事务读数据,不允许修改数据,如果其他事务要再对该行加锁,只能加共享锁;排他锁是修改数据时加的锁,可以读取和修改数据,一旦一个事务对该行数据加锁,其他事务将不能再对该数据加任务锁

未提交读(Read Uncommitted):在事务 A 读取数据时,事务 B 读取数据加了共享锁,修改数据时加了排它锁。这种隔离级别,会导致脏读、不可重复读以及幻读。

已提交读(Read Committed):在事务 A 读取数据时增加了共享锁,一旦读取,立即释放锁,事务 B 读取修改数据时增加了行级排他锁,直到事务结束才释放锁。也就是说,事务 A 在读取数据时,事务 B 只能读取数据,不能修改。当事务 A 读取到数据后,事务 B 才能修改。这种隔离级别,可以避免脏读,但依然存在不可重复读以及幻读的问题。(不可重复读:当事务A第二次读数据时,读到的可能是B修改后的数据)

可重复读(Repeatable Read):在事务 A 读取数据时增加了共享锁,事务结束,才释放锁,事务 B 读取修改数据时增加了行级排他锁,直到事务结束才释放锁。也就是说,事务 A 在没有结束事务时,事务 B 只能读取数据,不能修改。当事务 A 结束事务,事务 B 才能修改。这种隔离级别,可以避免脏读、不可重复读,但依然存在幻读的问题。(幻读:A在事务过程中,添加了一两行记录时,B可能)

可序列化(Serializable):在事务 A 读取数据时增加了共享锁,事务结束,才释放锁,事务 B 读取修改数据时增加了表级排他锁,直到事务结束才释放锁。可序列化解决了脏读、不可重复读、幻读等问题,但隔离级别越来越高的同时,并发性会越来越低。

但这种通过锁方式实现的事务,性能不高(一旦数据被加上排他锁,其他事务将无法加入共享锁,且处于阻塞等待状态,如果一张表有大量的请求,这样的性能将是无法支持的。
InnoDB 中的 RC 和 RR 隔离事务是基于多版本并发控制(MVCC)实现高性能事务

MVCC 对普通的 Select 不加锁,如果读取的数据正在执行 Delete 或 Update 操作,这时读取操作不会等待排它锁的释放,而是直接利用 MVCC 读取该行的数据快照(数据快照是指在该行的之前版本的数据,而数据快照的版本是基于 undo 实现的,undo 是用来做事务回滚的,记录了回滚的不同版本的行记录)。MVCC 避免了对数据重复加锁的过程,大大提高了读操作的性能。

参考

1、04-事务-JavaGuide
2、34 | MySQL调优之事务:高并发场景下的数据库事务调优-极客时间
3、03 | 事务隔离:为什么你改了我还看不见?-极客时间
4、04-事务|Innodb中的事务隔离级别和锁的关系 - 美团技术团队
5、15丨初识事务隔离:隔离的级别有哪些,它们都解决了哪些异常问题?
6、23 | MySQL是怎么保证数据不丢的?-极客时间
7、MySQL 的 crash-safe 原理解析
8、更新SQL执行过程
9、31丨为什么大部分RDBMS都会支持MVCC?