mysql的锁貌似有很多啊,查了大部分资料,

什么表锁,行锁,页锁

共享锁,排他锁,意向锁,读锁,写锁

悲观锁,乐观锁。。

我去,真想问一句,有没有 金锁?我还范冰冰呢。。。

哎呀怎么感觉好乱啊。那么把它好好整理总结下吧。

后边还有对在innodb下的mvcc理解与举例,在并发量的访问下如何保持高效一致?简单易懂了解下,听朋友说大公司面试也爱问这个。

表/行/页-锁:

表级锁(table-level locking):MyISAM和MEMORY存储引擎

行级锁(row-level locking) :InnoDB存储引擎

页面锁(page-level-locking):BDB存储引擎


表级锁:开销小,并发低,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度也最低

行级锁:开销大,并发高,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。

共享/排他锁

共享锁又称读锁,是读取操作创建的锁。其他用户可以并发读取数据,但任何事务都不能对数据进行修改(获取数据上的排他锁),直到已释放所有共享锁。

排他锁又称写锁,如果事务T对数据A加上排他锁后,则其他事务不能再对A加任任何类型的封锁。获准排他锁的事务既能读数据,又能修改数据。

Mysiam锁模式

MyISAM在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执行更新操作(UPDATE、DELETE、INSERT等)前,会自动给涉及的表加写锁。

a、对MyISAM表的读操作(加读锁),不会阻塞其他进程对同一表的读请求,但会阻塞对同一表的写请求.只有当读锁释放后才会执行其它进程的写操作。

b、对MyISAM表的写操作(加写锁),会阻塞其他进程对同一表的读和写操作,只有当写锁释放后,才会执行其它进程的读写操作。


innodb锁模式

意向锁是InnoDB自动加的,不需要用户干预。

对于insert、update、delete,InnoDB会自动给涉及的数据加排他锁(X);对于一般的Select语句,InnoDB不会加任何锁,事务可以通过以下语句给显示加共享锁或排他锁。

共享锁: SELECT ... LOCK IN SHARE MODE;

排他锁: SELECT ... FOR UPDATE;

MVCC(Multiversion concurrency control)

一个很难懂得概念,查阅了很多资料与博客,下边做一个简单易懂的理解。

情景模拟:

在高并发的前提下,一定要注意这个前提。

事务L1修改某表中D的key值,还未提交;

事务L2同样也修改D的key值,提交;然后L1提交。

发生了什么?

L1从D读取key:123对应的值100

L2从D读取key:123对应的100

L1对值增加1,将key:123更新为100 + 1

L2对值增加2,将key:123更新为100 + 2

如果L1和L2串行执行,key:123对应的值将为103,但上面并发执行中L1的执行效果完全被L2所覆盖,实际key:123所对应的值变成了102。就因为L1事务没提交呢,L2又来了。

那如何处理呢?

方法一:

加锁呗。前边不都是在说这个锁的问题呢,把他加写锁,等L1执行完再执行L2。可以是可以,但是发生了排队,并发下降了。这是一种悲观一般把基于锁的并发控制机称成为悲观机制。

方法二:

为了实现可串行化,同时避免锁机制存在的各种问题,我们可以采用基于多版本并发控制(Multiversion concurrency control,MVCC)思想的无锁并发机制,终于把要说的引出来了!人们一般把基于锁的并发控制机称成为悲观机制(悲观锁),而把MVCC等机制称为乐观机制(乐观锁)。加入版本号的一个机制,由D维护该版本号,每次数据有更新就增加版本号,通过版本号来更加高效的管理事务一致性与高并发的问题。

因为锁机制是一种预防性的,读会阻塞写,写也会阻塞读,当锁定粒度较大,时间较长是并发性能就不会太好;而MVCC是一种后验性的,读不阻塞写,写也不阻塞读,等到提交的时候才检验是否有冲突,由于没有锁,所以读写不会相互阻塞,从而大大提升了并发性能。

以上就是Mysql-各种锁区分与MVCC的详解的内容,更多相关内容请关注Work网(www.php.cn)!

08-18 06:07