并发控制
锁粒度
MySQL 中提供了两种锁粒度:表级锁、行级锁。
- 表锁:写锁的优先级高于读锁;写锁的请求可以插入到读锁的前面,但读锁的请求却不能插入到写锁的前面;
- 行级锁:行级锁只在存储引擎层实现,在服务器层没有实现;
尽量只锁定需要修改的那部分数据,而不是所有的资源。锁定的数据量越少,发生锁争用的可能就越小,系统的并发程度就越高。
但是加锁需要消耗资源,锁的各种操作(包括获取锁、释放锁、以及检查锁状态)都会增加系统开销。因此锁粒度越小,系统开销就越大。
锁类型
1.读写锁
- 互斥锁(Exclusive),简写为 X 锁,又称写锁。
- 共享锁(Shared),简写为 S 锁,又称读锁。
2.意向锁
意向锁在原来的 X/S 锁之上引入了 IX/IS,IX/IS 都是表锁,用来表示一个事务想要在表中的某个数据行上加 X 锁或 S 锁。
事务
事务:事务是一组原子性的SQL查询,或者说一个独立的工作单元。换句话说,事务内的语句,要么全部执行成功,要么全部执行失败。
事务的标准特征ACID:原子性(atomicity)、一致性(consistency)、隔离性(isolation)和持久性(durability)。
原子性:一个事务必须被视为一个不可分割的最小工作单元,要么全部提交成功,要么全部失败回滚。
一致性:数据库总是从一个一致性的状态转换到另一个一致性的状态。
隔离性:一个事务所做的修改在最终提交以前,对其他事务是不可见的。
持久性:一旦事务提交,则其所做的修改就会永久保存到数据库中。
事务的隔离级别:未提交读(READ UNCOMMITTED)、提交读(READ COMMITTED)、可重复读(REPEATABLE READ)、可串行化(SEAIALIZABLE)。
READ UNCOMMITTED(未提交读):事务可以读取未提交的数据,也叫脏读,实际中很少使用。
READ COMMITTED(提交读):一个事务从开始直至提交前,所做的任何修改对其他事务都是不可见的,也叫不可重复读,因为两次执行同样的查询,可能结果不同。
REPEATABLE READ(可重复读):保证了在同一个事务中多次读取同样记录的结果是一致的。解决了脏读的问题,但是无法解决幻读问题。
SEAIALIZABLE(可串行化):最高的隔离级别。通过强制事务串行执行,避免了幻读。SEAIALIZABLE会在读取的每一行数据上都加锁,所以可能导致大量的超时和锁争用的问题,实际中很少使用。
幻读(Phantom Read):指当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行(Phantom Row)。
死锁
两个或者多个事务在同一资源上相互作用,并请求锁定对方占用的资源,从而导致恶性循环的现象。
死锁的产生有双重原因:1、真正的数据冲突,比较难避免。2、存储引擎的实现方式造成的。