mysql事务隔离级别及实现原理

1. Mysql事务

MySQL 事务都是指在 InnoDB 引擎下,MyISAM 引擎是不支持事务的。

数据事务是只一组数据操作的执行,在事务内操作要么全部成功或失败。

2. 事务的四大特性(ACID)

(ACID) 指的是在数据库事务正确执行的四个基本要素的缩写。

特性 描述
原子性(Atomicity) 1. 原子性比较好理解,事务中的一切操作,要么全部执行成功要么全部失败
2. 原子性一旦开启就只能到结束,如果程序线程中断,将回滚到事务最初未操作的状态
一致性(Consistency) 一致性是只事务内数据只能回到一个状态。要么成功修改状态,要么失败初始状态
持久性(Isolation) 持久性就简单粗暴,事务执行成功数据保存在磁盘永久有效。程序关闭、宕机都可以恢复数据
隔离性(Durability) 1. 读未提交(READ UNCOMMITTED)
2. 读提交(READ COMMITTED)
3. 可重复读(REPEATABLE READ)
4. 串行化(SERIALIZABLE)

3. 概念

1. 脏读

脏读指读到了其他事务未提交的数据,未提交意味着这些数据可能会回滚,可能最终不会存到数据库中,读到了不存在的数据。这就是脏读。

2. 幻读

幻读指A事务在根据条件查询时出现的数据,B事务在符合A事务查询条件表中插入了一条数据。A事务再次查询时多了一条数据,是刚才B事务插入的数据。感觉出现了幻觉,这就叫幻读。

3. 不可重复读

一个事务只能读到另一个已经提交的事务修改过的数据,并且其他事务每对该数据进行一次修改并提交后,该事务都能查询得到最新值。

4. 事务隔离级别

隔离级别 脏读(Dirty Read) 不可重复读(NonRepeatable Read) 幻读(Phantom Read)
读未提交(RU)
读提交(RC) ×
可重复读(RR) × ×
串行化(S) × × ×

5. 隔离级别的实现原理

事务隔离级别 实现方式
读未提交(RU) 事务对当前被读取数据时不加锁。
事务在更新某数据的瞬间(发生更新的瞬间),对其加行级共享锁,直到事务结束才释放。
读提交(RC) 事务对当前被读取的数据加行级共享锁(当读到时才加锁),一旦读完该行,立即释放该行级共享锁。
事务在更新某数据的瞬间(发生更新的瞬间),对其加行排他锁,直到事务结束才释放。
可重复读(RR) 事务对当前被读取的瞬间就是开始读取的瞬间,对其加行级共享锁,直到事务结束才释放。
事务在更新某数据的瞬间(发生更新的瞬间),对其加行排他锁,直到事务结束才释放。
串行化(S) 事务在读取数据时,必须先对其加表级共享锁,直到事务结束才释放。
事务在更新数据时,必须先对其加表级排他锁,直到事务结束才释放。

6. 共享锁与排他锁

6.1. 共享锁

共享锁又称读锁,是读取操作创建的锁。其他用户可以并发读取数据,其他任何事务都不能对数据进行修改,直到已释放所有共享锁。

共享锁:其它事务可以继续加共享锁,但不能加排它锁

6.2. 排他锁

排他锁又称为写锁,顾名思义,排他锁就是不能与其他所并存,如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁,包括共享锁和排他锁,但是获取排他锁的事务是可以对数据就行读取和修改。

排他锁:其它事务不能再获得任何锁