MySQL锁机制的了解:
序言:
如果保证数据并发访问一致性和有效性,是所有必须解决的一个问题
另外,锁冲突也是影响数据库并发性能的一个重要因素
应用程序在选择类型的时候,根据自身项目的需要,选择对的锁类型
锁类型:
1. MyISAM和Menory存储引擎使用的是表锁,BDB引擎使用的是页级锁,由于BDB的引擎以成为历史,这边就不多解释
2. InnoDB支持的引擎既支持表锁,也支持行锁,默认情况下使用的是行锁
3. 所谓表锁:是锁住一张表,开销小,加锁快,粒度大(数据大)不会出现死锁
4. 所谓行锁:是锁住一行,开销大,加锁慢,粒度小,不会出现死锁,并发度很高
5. 所谓页锁:是锁住一整页数据的表。
6. 仅仅在锁的角度来看,表锁更适合在查询并发不同的数据时,只有少量的索引类型更新数据时使用
7. 行锁的角度来看,行锁更适合在查询并发更新不同的数据时 ,更适合使用
InnoDB行锁其中的两个锁(共享锁、排他锁):
共享锁(lock in share mode):只可以读,不可以写(共享锁与其他任何锁一起使用不会冲突除了排他锁)
排他锁(for update):既不可读,也不可以写(共享所以其他任何锁一起使用都会冲突)
执行sql、insert,update,delete默认都会加上一个排他锁
* 共享锁:允许一个事务读取一行数据,不允许其他事务读取相同的数据
(如果一个事务内的代码区域的sql语句加上了一个共享锁,
另外一个事务sql语句加上了排他锁的话,必须等待第一个事务的锁释放后,
才可以得到结果数据,如果是共享锁与共享锁,则不用等到锁释放,立即可得到数据)
* 排他锁:允许一个事务更新一行数据,阻止其他事务更新相同的数据(不管是共享锁还是排他锁,遇到排他锁都无法更新。因为排他锁跟任何锁共同使用下都会冲突)
* 悲观锁:必须使用到锁。表锁、行锁、共享锁、排他锁,都称之为悲观锁
* 乐观锁:不需要用到锁
最后:
如果一个事务代码区域内的sql语句的锁不兼容的话,必须等待其他事务的锁释放后才可以得到数据
反之,一个事务代码区域内的sql语句的锁兼容的话,不需要等待其他事务的锁释放后才能得到数据
锁的兼容性:
第一个事务使用的共享锁、第二个事务使用了排他锁(而第二个事务必须等待第一个事务的锁释放后才能得到数据)
相反,第一个事务使用的是共享锁、而第二个事务使用的共享锁不需要等待事务1的锁释放才能得到数据
排他锁与其他锁使用都会冲突
共享锁和排他锁锁住的是一行、意向共享锁、意向排他锁锁住的是一整张表