数据库的锁

在数据库管理中,锁是一种关键的工具,用于协调并发访问数据库的共享资源。MySQL作为一种常见的关系型数据库管理系统,也采用了多种锁机制来确保数据的完整性和一致性。

什么是锁

数据库的锁是为了支持对共享数据的并发访问,提供数据的完整性和一致性。

死锁

两个或者两个以上的进程在执行过程中,同时竞争共享资源造成相互等待现象。

如何排查死锁?

死锁是指两个或多个进程在互相等待对方释放资源的情况下无法继续执行的状态。为了排查死锁,可以采取以下步骤:

  1. 检查是否存在死锁:观察系统运行状况,检查是否有进程处于阻塞状态。

  2. 分析死锁原因:通过分析日志、堆栈信息等方式确定哪些资源被占用,并且哪些线程正在等待这些资源。

  3. 解除死锁:解除死锁的方法包括撤销某些请求、强制中断某些进程、增加资源数量等。

  4. 预防死锁:在编写程序时应该避免出现竞争条件和不恰当使用同步机制导致的问题,同时也可以采用一定策略来预防发生死锁。

总之,在排查和解决死锁问题时需要仔细分析并找到具体原因,以便能够更好地进行处理。

怎么避免死锁?

  1. 为表添加合理的索引。
  2. 选择合理的事务大小,小事务发生锁冲突的几率也更小
  3. 对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁产生的概率。

锁分类

从锁的粒度来看,又可以分为行锁、表锁、页锁

从锁概念来看,可分为悲观锁和乐观锁。

从锁的功能上看,可以分为共享锁、排他锁(独占锁)、意向锁等。共享锁也称S锁,排他锁也被称为X锁。

行锁、表锁、页锁

行锁

行级锁是Mysql中锁定粒度最细的一种锁,表示只针对当前操作的行进行加锁。行级锁能大大减少数据库操作的冲突。其加锁粒度最小,但加锁的开销也最大。行级锁分为共享锁排他锁

特点

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

支持引擎

innodb支持行锁,myisam不支持行锁。

表级锁

表级锁是MySQL中锁定粒度最大的一种锁,表示对当前操作的整张表加锁,它实现简单,资源消耗较少,被大部分MySQL引擎支持。最常使用的MYISAM与INNODB都支持表级锁定。表级锁定分为表共享读锁(共享锁)表独占写锁(排他锁)

特点

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

支持引擎

innodb和myisam均支持表锁。

触发条件

1.没有走索引

2.DDL也发生锁表,例如:利用 alter 语句修改或新增字段的时候

页级锁

页级锁是MySQL中锁定粒度介于行级锁和表级锁中间的一种锁。表级锁速度快,但冲突多,行级冲突少,但速度慢。所以取了折衷的页级,一次锁定相邻的一组记录。BDB支持页级锁

特点

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

支持引擎

BDB支持页级锁

悲观锁和乐观锁

悲观锁

指的是在操作数据的时候比较悲观,悲观地认为别人一定会同时修改数据,因此悲观锁在操作数据时是直接把数据上锁,直到操作完成之后才会释放锁,在上锁期间其他人不能操作数据。

乐观锁

指的是在操作数据的时候非常乐观,乐观地认为别人不会同时修改数据,因此乐观锁默认是不会上锁的,只有在执行更新的时候才会去判断在此期间别人是否修改了数据,如果别人修改了数据则放弃操作,否则执行操作。

实现方式

悲观锁:for update

乐观锁:版本号机制

乐观锁是无锁的吗?

乐观锁是一种基于版本控制的锁,它不会阻塞其他事务的访问,并且不会抢占所有权。但是它并不是完全无锁的,因为它仍然要求事务在读取和修改数据之间进行检查,并确保在修改过程中数据没有被其他事务更改。如果冲突发现了,那么事务必须回滚并重试,这可能会导致一些等待时间。因此,尽管它不像悲观锁那样需要显式地加锁,但它仍然涉及到某种形式的锁定或同步操作。

优缺点

1、乐观锁并未真正加锁,效率高。一旦锁的粒度掌握不好,更新失败的概率就会比较高,容易发生业务失败。

2、悲观锁依赖数据库锁,效率低。更新失败的概率比较低。

共享锁、排他锁、意向锁

共享锁

共享锁(Shared Lock)又称读锁,允许多个事务同时读取一个数据项,但不允许写入。

实现方式:SELECT ... LOCK IN SHARE MODE;

排他锁

排他锁(Exclusive Lock)又称写锁,一次只允许一个事务写入或修改数据项,其他事务不能同时读取或写入。

实现方式:SELECT ... FOR UPDATE;

意向锁

意向锁是表级锁,其设计目的主要是为了在一个事务中揭示下一行将要被请求锁的类型。

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

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