MySQL的事务
MySQL 通过 `undo log`(回滚)、`redo log`(持久化)、锁机制、MVCC 和事务隔离级别,确保事务满足 ACID,提供高效并发控制!
事务的锁机制**
|**行锁**(Record Lock)|**行级**|细粒度锁,性能高,但死锁风险大|
|**表锁**(Table Lock)|**整张表**|粒度大,适用于 `ALTER TABLE`|
|**间隙锁(Gap Lock)**|**范围查询**|防止幻读(可避免并发插入)|
**行锁**:开销大,加锁慢,会出现死锁,锁定粒度小,发生锁冲突的概率低,但并发度高。仅对指定的记录进行加锁,这样其它进程还是可以对同一个表中的其它记录进行操作
**表锁**:开销小,加锁快,无死锁,锁定粒度大,发生锁冲突的概率最高,并发度低。直接锁定整张表,在锁定期间,其它进程无法对该表进行写操作。如果是写锁,则其它进程则读也不允许。表锁分为读锁(共享锁(shared lock),针对同一份数据,多个读操作可以同时进行而不会互相影响(select))和写锁(排他锁(exclusive lock),在当前操作没完成之前,会阻塞其它读和写操作(update、insert、delete))
#### **事务中的两种锁**
|**共享锁(S锁)**|允许多个事务**读**|`SELECT ... LOCK IN SHARE MODE`|
|**排他锁(X锁)**|只能**单个事务**修改数据|`SELECT ... FOR UPDATE`
### **MVCC(多版本并发控制)**
MVCC 通过 **undo log 生成多个数据版本**,避免加锁,提高并发性能。
- **快照读**:直接读取未加锁的数据(MVCC 负责读取历史版本)。
- **当前读**:读取最新版本(`SELECT ... FOR UPDATE` 需要加锁)。
MVCC主要由下面两个核心功能组成,undo log实现数据的多版本,ReadView实现多版本的并发控制。
1. 当一个事务尝试改动某条数据时,会将原本表中的旧数据放入undo log中。
2. 当一个事务尝试查询某条数据时,MVCC会生成一个ReadView快照。
InnoDB通过MVVC、undo log和redo log实现了事务的ACID特性,