1. 并发控制
1.1 读写锁
共享锁(读锁S):读锁是共享的,或者说是互不阻塞。多个客户可以同时读取同一数据,而互不干扰。
排他锁(写锁X):写锁是排他的,一个写锁会阻塞(排斥)其他的写锁和读锁,以确保同一时间内只有一个用户才能执行写入。
1.2 锁粒度
加锁需要消耗资源,锁的各种操作,比如获得锁、检查锁是否已经解除、释放锁等,因此需要锁策略。锁策略,是在锁的开销和数据的安全性之间寻求平衡。
表锁:最基本、锁开销最小的锁策略。它会锁定整张表,一个用户在对表进行写操作前需要先获得写锁,这将会阻塞其他用户对该表的所有读写操作。
行级锁:可以最大程度地支持并发处理,同时也带来了最大的锁开销。
2. 事务
2.1 ACID特性
最经典的例子:银行转账。比如:A转账1000元到B。①检查A是否有1000元;②A减去1000元;③B加上1000元。
原子性(atomicity)
一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚。
一致性(consistency)
数据库总是从一个一致性的状态转换到另外一个一致性的状态。
隔离性(isolation)
通常,一个事务所做的修改在最终提交以前,对其他事务是不可见的。当然这里涉及到隔离级别的问题。
持久性(durability)
一旦事务提交,则其所作的修改就会永久保存到数据库中。
2.2 隔离级别
介绍隔离级别之前,需要先了解他们可以处理的并发问题。
并发问题 | 描述 | 解决 |
---|---|---|
丢失修改 | A、B同时修改数据1,A修改了数据1后提交,B和A同时读到了数据1,在A修改后提交了修改导致A的修改丢失。 | 加X锁到事务结束 |
脏读 | A修改数据1后提交事务,B读到了数据1,此时A又回滚事务。B读到了脏数据。 | 加X锁到事务结束、加S锁 |
不可重复读 | A读了数据1、数据2由数据1和数据2得到数据3,B修改数据1的值,A再次验证数据3的值,发现不可重复读。 | 加X锁到事务结束、加S锁到事务结束 |
可串行化 | A将表1其中所有数据1改成数据2,同时B往表1中插入数据1。A发现又出现了数据1。 | 串行执行 |
隔离级别 | 丢失修改 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|---|
READ UNCOMMITTED(未提交读) | × | √ | √ | √ |
READ COMMITTED(提交读) | × | × | √ | √ |
REPEATABLE READ(可重复读) | × | × | × | √ |
SERIALIZABLE(可串行化) | × | × | × | × |
2.3 死锁
死锁是指两个或多个事务在同一个资源上相互占用,并请求锁定对象占用的资源,导致恶性循环的现象。
2.5 MySQL中的事务
MySQL采用自动提交(Autocommit)模式。
提供了两种事务型的存储引擎:InnoDB和NDB Cluster。
3. MVCC
Multi Version Concurrency Control,多版本并发控制。
4. 最后
点击获取可以查看我更多更详尽的阅读笔记哈,如有帮助的话,请给我一个star,谢谢支持~
参考
《高性能MYSQL》第1章