多种角度看数据库锁分类

目录

1.程序员的角度(网上这么说,个人理解应该是业务的角度),分为乐观锁和悲观锁。

2.锁力度上,分为行级锁和表级锁。主要针对innodb存储引擎而言,myisam和memory支持表级别锁,dbd还有页锁,此处不多介绍。

3.innodb行锁类型(mysql王者晋级之路,这本书上作者这么分的,个人理解应该是数据库角度分类),共享锁(S,又称读锁),排它锁(X,又称写锁),意向锁(分两种,意向共享锁IS和意向排它锁IX),MDL锁(meta data lock)。

4.innodb行锁种类,单个行记录的锁,间隙锁和Next-key锁

5.减少死锁概率的四种方法


看过很多数据库锁相关的文章,乐观锁、悲观锁、行锁、表锁等等,去了解了各自含义,可是在实际开发中还是有点蒙圈。大概是太多种不同角度的锁放在一起,导致分不清了。以下是开发中遇到并稍微了解到的一些做下大致总结,方便记忆和理解,应该会有些不正确的地方,待慢慢修正。

1.程序员的角度(网上这么说,个人理解应该是业务的角度),分为乐观锁和悲观锁。

1)字面意思上就是乐观锁就是包容的认为别人不会来改变数据,所以过来一个请求,取接受,再去对比,没问题就更新,有问题就拒绝。其中判断有没有问题可以通过时间戳,或者通过某个字段累加判断,有点类似java中cas(应该也是乐观锁的一种)。

2)悲观锁就是悲观的认为别人都会改变既有数据,所以在操作前会锁定,避免外界修改正在处理的数据。

 

2.锁力度上,分为行级锁和表级锁。主要针对innodb存储引擎而言,myisam和memory支持表级别锁,dbd还有页锁,此处不多介绍。

1)行锁,就是锁定对应行及相应索引关联的行。如update某一行时,这是会锁定该行,但是仍可修改其他行,这样并发相对高些,行锁也是innodb默认锁级别。

2)表锁,是指锁定该表,当涉及到更新表中大部分数据或者多个表关联时,可以考虑使用表级锁,但是一般不建议,毕竟开销太大,并发太低。

 

3.innodb行锁类型(mysql王者晋级之路,这本书上作者这么分的,个人理解应该是数据库角度分类),共享锁(S,又称读锁),排它锁(X,又称写锁),意向锁(分两种,意向共享锁IS和意向排它锁IX),MDL锁(meta data lock)。

1)共享锁,一个事务在进行读时获取了该行的读锁,其他事务可以读,但是不可以写。分两种,一种是自动提交某事下的select,这种默认提交,直接返回结果,不加锁。另一种select *** lock in share mode,这种其他事务可以读,但是要写需要等待。

2)排它锁,一个事务获得了写锁,其他事务就需要等待。一般改都会加上写锁,还有一种特殊的查询,select ** for update也会加。

3)意向锁,是指一个事务获取共享或者排它锁前,先获取意向共享或者排它锁,是表级锁,避免其他事务进行DDL操作。

4)MDL锁,mysql5.5及之后版本有,用于保证表中元数据的一致性,如开启一个事务后,MDL锁默认就会打开,不能执行DDL操作,如新增表字段等。

 

4.innodb行锁种类,单个行记录的锁,间隙锁和Next-key锁

1)单个行记录的锁,主键和唯一索引都是行记录锁模式,在read-commit隔离级别下,只有这种锁模式。

2)间隙锁,是在repeatable read隔离级别下的锁,即如果select * from id<20,则在该范围内不允许插入新的数据,只锁定范围本身,但是不锁定单个行,也就是说可以修改该范围内的数据,也就是我们所说的幻读现象。

3)Next-key锁,是记录锁和间隙锁的组合,即在扫描某个索引时,不但对该索引对应的行加锁,也会对两边的数据,加上间隙锁,如索引列id<85,插入id=85的列也是无法插入的。

 

5.减少死锁概率的四种方法

1)升级锁力度,可以将行锁升级为表锁,锁定整张表,减少死锁概率。

2)在一个事务中,尽量一次性锁定所有所需资源,减少死锁概率。

3)尽量使用小事务,避免使用大事务,及时提交和回滚,减少死锁概率。

4)多个并发事务同时操作多张表或者多列数据时,尽量按照相同顺序,减少死锁概率。

 

参考:张甦著mysql王者晋级之路

 

 

 

 

 

 

 

你可能感兴趣的:(数据库)