锁是数据库系统区别于文件系统的一个关键特性。mysql
锁机制用于管理对共享资源的并发访问,提供数据的完整性和一致性。sql
InnoDB存储引擎不只会在行级别上对表数据上锁,还会在数据库内部其余多个地方使用锁,从而容许对多种不一样资源提供并发访问。如:操做缓冲池中LRU列表,删除、添加、移动LRU列表中的元素,为了保证数据的完整性,必须有锁的介入。数据库
InnoDB存储引擎锁的实现与Oracle相似,提供一致性的非锁定读、行级锁支持。并发
有多少种数据库,就可能有多少种锁的实现方法。异步
共享锁(S Lock),容许事务读一行数据。spa
排他锁(X Lock),容许事务删除或者更新一行数据。日志
show engine innodb status; information_schame下的表innodb_trx、innodb_locks、innodb_lock_waits ( mysql> select * from innodb_trx\G ### 只显示了当前运行的innodb事务 mysql> select * from innodb_locks\G ### 直接反映了锁的一些状况 mysql> select * from innodb_lock_waits\G ### 事务量大时,直观反映当前事务的等待 )
例子:code
只显示了当前运行的innodb事务,并不能直接判断锁的一些状况。orm
事务trx_id=730FEE向表parent加了一个X的行锁,
事务trx_id=7311F4向表parent申请了一个S的行锁,
lock_date=1表示都申请表parent中主键=1这一行blog
事务量大时,直观反映当前事务的等待。
InnoDB存储引擎下,这是默认的读取方式。即:读取不会占用和等待表上的锁。
定义:若是读取的行正在执行update或delete操做,这时读取的操做不会所以去等待行上锁的释放,而是去读取行的快照数据(该行以前的数据,经过undo段来实现;一个行记录可能不止一个快照数据,通常称这种技术为多版本并发控制MVCC)。
使用:事务隔离级别read committed和repeatable read(innodb默认存储引擎)。
RC下,对于快照数据,非一致性读老是读取被‘锁定行的最新一份快照数据’。
RR下,对于快照数据,非一致性读老是读取‘事务开始是的行数据版本’。
例子:
时间5:RC、RR下结果id=1 ;
时间6:RC下结果为空,RR下结果id=1。
定义:某些状况下,用户须要对数据库读取操做进行加锁以保证数据逻辑的一致性。
加锁语句:
select ... for update; ### 对读取的行记录加一个X锁
select ... lock in share mode; ### 对读取的行记录加一个S锁
说明:以上加锁语句必须在一个事务中,当事务提交,锁就释放了(在使用锁定语句时,务必加上begin,start transaction, set autocommit=0)
锁机制会形成以下问题:
脏页 : 在缓冲池中已经被修改的页,可是尚未刷新到磁盘中,即:数据库实例内存中的页和磁盘中的页的数据是不一致的,固然在刷新到磁盘以前,日志已经备写入到了重作日志(redo log)中。
说明:对于脏页的读取,是很正常的。它是因为数据库实例内存和磁盘的异步形成的,最终脏页会刷回磁盘,并不影响数据的一致性。
脏数据:指事务对缓冲池中行记录的修改,而且尚未被commit。
说明:若是读取到了脏数据,即一个事务能够读到另一个事务未提交的数据,这显然违背了数据库的隔离性。
脏读:就是早不一样的事务下,当前事务能够读到另外事务未提交的数据(read uncommited事务隔离级别下)。
不可重复读:在同一事务中,两次读取同一数据,获得内容不一样
事务1:查询一条记录 -------------->事务2:更新事务1查询的记录 -------------->事务2:调用commit进行提交 事务1:再次查询上次的记录 ***此时事务1对同一数据查询了两次,可获得的内容不一样,称为不可重复读
不可重复读与脏读的区别:脏读是读到未提交的数据,而不可重复读读到的倒是已经提交的数据,可是违反了一致性的要求。
幻读:同一事务中,用一样的操做读取两次,获得的记录数不相同
事务1:查询表中全部记录 -------------->事务2:插入一条记录 -------------->事务2:调用commit进行提交 事务1:再次查询表中全部记录 ***此时事务1两次查询到的记录是不同的,称为幻读
详细解释:幻读是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的所有数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,之后就会发生操做第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉同样。
不可重复读与幻读的区别不可重复读的重点是修改:一样的条件, 你读取过的数据,再次读取出来发现值不同了幻读的重点在于新增或者删除:一样的条件, 第 1 次和第 2 次读出来的记录数不同