顾名思义,MySQL锁是为了不让别人访问。
●根据锁的范围:表级锁、行级锁、页级锁。
●不同的存储引擎使用的锁也是不一样的。
▶Myisam:表级锁
当我们对表进行操作的时候,mysql会自动给这张表加锁,为了看出来效果,我们需要手工的加锁。
1.共享读锁(在当前会话加了一个读锁之后,不管是当前会话还是其他会话都是不能写的。其他人也能读):当我读取表里的一些内容的时候,mysql会对这张表加上一个读锁,其他的会话也是可以给这张表加读锁的,但是其他回话不能给这张表加写锁。
**加读锁 lock table 表名 read
解锁 unlock tables**
i)如果有多张表的话,在一个会话里,如果给一张表加了读锁,其他表没有加读锁,那么那些没有加锁的表,在当前会话里是不能使用的。
ii)若有两张表aa和bb,他们是相关联的,如果给aa表加锁,而bb表没有加锁,那么其他会话是不能修改aa的,但是可以修改bb表,容易造成数据的不一致性。所以,当给一张表加锁的时候,要把其他所有的表全部都加锁。
lock table aa read,bb read;
iii)当给一张表加了读锁之后,那么其他会话是不能再写的,如果想让其他会话可写,需在加锁的时候加上local选项。这样在当前会话不可写,但在其他会话是可以写的(其他会话可以写的一个前提是:这张表是不能有黑洞的,只能在最后面插入。黑洞是指中间id等数据不连续)。所以,即使在锁定会话的时候加了local,其他会话也只能在最后一行insert,而不能做任何的update。(如果当前会话解锁,其他会话插入可填补一个黑洞)lock table aa read local;
2.共享写锁(其他人不可查询或更改,但本会话可以插入数据):当我们对一张表写数据的时候如update,insert等,mysql会自动的给这张表加上一个共享写锁,如果在一个会话里加了一个共享写锁的话,那么其他任何会话都不能在加读锁或者写锁。lock table 表名 write
▶Innodb行级锁,粒度更精细。(要想使用Innodb的锁,必须要开启事务,否则不生效。)更适合大并发量插入。是基于索引的锁,如果表没有索引的话,那么将使用的是表级锁。因为innodb是基于事务的,所以容易出现死锁。
⑴.脏读:如果没有提交,导致内存里的数据和硬盘里的数据不一致
⑵.不可重复性:如一个用户查询id=5,tom5。再次查询id=5,tom6
⑶.幻读
⑷.死锁
1.共享锁:当读取数据的时候,会给这行数据加上一个共享锁,当加了共享锁之后,其他会话也是可以加共享锁的,但是其他会话是不能修改数据(不能加排它锁)。如果多个会话同时要给一个资源加排他锁,那么此时就会出现死锁。select *from 表名 where id=1 lock in share mode
commit释放锁
2.排他锁:所谓排他锁,就是写锁。当我对一行内容来进行写的时候,会给这行内容加上一个排他锁,其他会话是不能加共享锁的,更不能加排它锁。
select id,name from aa where id=1 for update;
查看innodb中加锁情况
show engine innodb status G
乐观锁(Optimistic Locking)认为对同一数据的并发操作不会总发生,属于小概率事件,不用每次都对数据上锁,也就是不采用数据库自身的锁机制,而是通过程序来实现。在程序上,我们可以采用版本号机制或者时间戳机制实现。
悲观锁(Pessimistic Locking)也是一种思想,对数据被其他事务的修改持保守态度,会通过数据库自身的锁机制来实现,从而保证数据操作的排它性。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。