本文转载自:MySQL锁机制
1.行级锁定(row-level)
行级锁定的特点就是锁定对象的颗粒度很小,由于锁定颗粒度很小,发生锁定资源争用的概率也最小,能够给予应用程序尽可能大的并发处理能力。从而提高一些需要高并发应用系统的整体性能。
但是行级锁定也有不少弊端,由于锁定资源的颗粒度很小,所以每次获取锁和释放锁需要的操作就更多,带来的消耗自然也就更大了,此外,行级锁定也最容易发生死锁。
2.表级锁定(table-level)
该锁定机制最大的特点是实现逻辑非常简单,带来的系统处理成本最小,所以获取锁和释放锁的速度很快。由于表级锁一次会将整个表锁定,所以很好地避免困扰我们的死锁问题。
当然,锁定颗粒度大带来最大的负面影响就是出现锁定资源争用的概率也会最高,致使并发度大打折扣。
表级锁有2种模式:表共享锁、表独占锁
myisam:
myisam采用的是表级锁,对于表的读请求,不会阻塞其他用户对同一表的读请求,但是会阻塞对同一表的写请求。
对myisam的写操作,会阻塞其他用户对同一表的读、写操作。
myisam表的读、写操作之间是串行的。
myisam加锁:
在执行select操作前,会自动给涉及的所有表加读锁;在执行更新操作(update、delete、insert)前,会自动给涉及的表加写锁,这个过程不需要用户干预。
myisam的并发插入:
myisam也支持查询、插入并发进行。
当current_insert = 0时,不允许并发插入
当current_insert = 1时,如果myisam表没有空洞(表的中间没有被删除的行),允许在一个用户select时,另一个用户在表尾插入记录。这也是myisam的默认设置。
当current_insert = 2时,无论MyISAM表中有没有空洞,都允许在表尾并发插入记录。
myisam的锁调度:
之前说过,myisam的读锁和写锁是互斥的、串行的,一个进程请求myisam表的读锁时,此时另一个线程请求同一表写锁,这时候mysiam怎么调度?
答案是写进程优先获得锁,不仅如此,即使读请求先到锁等待队列,写请求后到,写锁也会查到读锁前面,这是因为myisam认为一般写请求比读请求重要。
也正是这样,myisam不太适合有大量更新和查询操作应用的原因,因为大量的更新操作会造成查询操作很难获得读锁,从而可能永远阻塞。
innodb:
innodb与myisam最大的区别有两点:一是innodb支持事务,二是innodb采用了行级锁
在innodb中,默认的事务隔离级别是repeatable(在oracle中是read commited)
innodb实现事务的隔离级别有两种方式:
一种是读取数据时对其加锁,阻止其他事务对数据进行修改
另一种是不用任何加锁,而是通过一定机制生成一个数据请求时间点的一致性数据快照,并用这个快照提供一定级别的(语句级或事务级)的一致性读取,
从用户的角度看,好像数据库提供了统一数据的多个版本,因此这种技术叫做多版本并发控制(MultiVersion Concurrency Control,简称MVCC)
innodb实现了两种类型的行锁:
共享锁(S): 允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁
InnoDB这种行锁实现特点意味着: 只有通过索引条件检索数据,InnoDB才使用行锁,否则,InnoDB将升级使用表锁。
小结:
对于InnoDB表,本章主要讨论以下几项内容