1.2 并发控制
1.2.1 读写锁
共享锁(读锁)。读锁是共享的,或者说是互相不阻塞的。多个客户在同一时刻可以同时读取一个资源,互不干扰。写锁是排他锁,也就是说一个写锁会阻塞其它的读锁和写锁。
1.2.2 锁粒度
一种提高共享资源并发性的方式就是让锁定对象更有选择性。理想方式:对修改的数据进行精确的锁定。锁定的数据量越少,系统的并发层度越高。
表锁
表锁是MySQL中最基本的锁策略,并且开销最小的策略。会锁定整张表,一个用户对表进行写操作钱,先活得写锁,这会阻塞其它用户对该表的所有读写操作。写锁币读锁有更高的优先级,因此一个写锁请求可能会被插入到读锁队列的前面
行级锁
行级锁可以最大程度地支持并发处理,在InnoDB及一些其它存储引擎中实现了行级锁。行级锁只在存储引擎层实现,服务层完全不了解存储引擎中的锁实现。
1.3 事务
事务就是一组原子性的SQL查询。事务内的语句,要么全部执行成功,要么全部执行失败。
原子性:
一个事务必须被视为不可分割的最小工作单元,整个事务中的所有炒作要么全部提交成功,要回全部失败回滚,对于一个事务来说,不可能执行其中一部分操作,这就是事务的原子性。
一致性:
数据库总是从一个一致性状态转换到另一个一致性状态。
隔离性:
通常来说(有事务隔离级别),一个事务所做的修改在最终提交以前,对其它事务是不可见的。
持久性:
一旦事务提交,则其所做的修改就会永久的保存到数据库中。即使系统奔溃,修改的数据也不会丢失。
1.3.1 隔离级别
读未提交:
在事务中的修改,即使没有提交,对其它事务也都是可见的。事务可以读取未提交的数据,这也被称为脏读,性能高,问题多,很少使用。
读已提交:
一个事务从开始直到提交之前,所做的任何修改对其它事务都是不可见的,导致不可重复读(两次同样的查询,得到的结果可能不一样)
即:在第一个事务中的两次读取数据之间,由于第二个事务的修改(提交了),第一个事务两次读到的数据可能就是不一样的
可重复读:
解决了脏读和不可重复读的问题。但是出现的幻读。一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为“幻读”。即:事务A读取到了事务B提交的新增数据,不符合隔离性。InnoDB存储引擎通过多版本控制(MVCC)解决了幻读的问题。
串行读:
最强隔离级别。强制事务串行执行。
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| 读未提交(Read Uncommitted) | 可能 | 可能 | 可能 |
| 读已提交(Read Committed) | 不可能 | 可能 | 可能 |
| 可重复读(Repeatable Read) | 不可能 | 不可能 | 可能 |
| 串行读(Serializable) | 不可能 | 不可能 | 不可能 |
1.3.2 死锁
死锁是指两个或者多个事务在同一资源上相互占用,并请求锁定对方占用的资源 ,从而导致恶性循环的现象。
1.3.3 事务日志
存储引擎在修改表的数据时只需要修改其内存拷贝,再把该修改行为记录到持久在硬盘上的事务日志中,而不用每次都将修改的数据本事持久到硬盘。
1.3.4 MySQL 中的事务
MySQL提供了两种事务烈性的存储引擎:InnoDB 和NDB Clouster。
自动提交:
默认采用自动提交模式。如果不是显式地开启一个事务,则每个查询都被当做一个事务执行提交操作。
隐式和显式锁定:
InnoDB采用的是两阶段锁定协议。在事务执行过程中,随时都可以执行锁定,锁只有再执行commit或者rollback的时候才会释放。MySQL也支持lock tables 和unlock tables ,这是服务层实现的,和存储引擎无关。一般不建议用。
1.4 多版本并发控制
MVCC的实现,是通过保存数据在某个时间点的快照来实现的。
InnoDB的MVCC,是通过在每行后面保存两个隐藏的队列来实现。这两个列,一个保存了行创建的时间,一个保存了行的过期时间(或删除时间)。存储的并不是实际的时间值,是系统版本号,每开始一个新的事务,系统版本号就会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行记录的版本号进行比较。
具体操作:
- select
InnoDB会根据以下两个条件检查每行记录:- InnoDB只查找版本早于当前事务的行(也就是,行的系统版本号小于或者等于事务的系统版本号),这样保证事务读取到的行,要么在事务开始前已经存在,要么是事务自身插入或者修改过的。
- 行的删除要么未定义,要么大于当前事务的版本号。保证读到的行在事务开始前未被删除
只有符合以上两个条件的记录,才能返回作为查询结果。
- insert
InnoDB为新插入的每一行保存当前系统版本号作为行版本号 - delete
为删除的每一行保存当前的版本号作为删除标识 - update
为插入的每一行新数据,保存当前系统版本号作为行版本号,同时保存当前系统版本号到原来的行作为删除版本号。
145

被折叠的 条评论
为什么被折叠?



