MySQL锁机制

1、什么是锁?

锁是计算机协调多个线程或者线程并发访问某一资源的机制。

2、表锁(偏读)

  2.1、表锁的基本操作

手动添加表锁lock table 表名字 read | write,表名字2 read | write  ......

释放表锁unlock tables  

查看表上加的锁:show open tables;

MySQL锁机制_第1张图片

对room表加锁就会显示:

  2.2、表锁两种模式

表共享读锁、表独占写锁

读锁:又称为共享锁,对同一份数据,多个读操作可以同时进行而互不影响

若事务T对数据对象A加上读锁,事务T只能读A不能修改A其他事务只能对其加读锁不可以加写锁直到T释放A上的读锁为止

当前session可以查询该表记录不能查询其他没有锁定的表

MySQL锁机制_第2张图片

MySQL锁机制_第3张图片

其他session可以查询或者更新未锁定

其他session不可以更新该表(被锁的表一直被阻塞除非session1对表释放锁

写锁:又称为排他锁,当前写操作没有完成前,它会阻断其他写锁读锁。(写锁独占

若事务T对数据对象A加上写锁,则只允许T读取和修改A,其他事务都不可以再对数据A再加任何类型的锁,直到T释放对A上的锁为止

当前session可以对该表增删改,不可以操作其他未被锁的表;

其他session则不可以进行任何操作,一直被阻塞,除非session1对该表释放锁。

MySQL锁机制_第4张图片

简而言之,就是读锁会阻塞写,但是不会阻塞读,而写锁则会把读和写都阻塞

   2.3、表锁支持的存储引擎

支持innodb、MYIsam,偏向MYIsam存储引擎

  2.4、使用场景

以查询为主、只有少量按索引条件更新数据的应用。

  2.5、特点

开销小,加锁快,不会出现死锁,发生所冲突的概率最高,并发度最低

3、行锁(偏写)

偏向Innodb存储引擎,Innodb行锁是通过给索引上索引项来实现的,意味着:只有通过索引条件检索数据

话句话说就是:在一张表中有索引才会使用行锁,否则innodb将使用表锁。

 3.1、行锁支持的存储引擎

支持的存储引擎:InnoDB

InnoDB与MyIsam的最大区别有两点:InnoDB支持事务InnoDB支持行级锁

3.2、特点

 3.2、Innodb存储引擎的表在使用索引时-行锁演示

sesson1 session2

更新但是session1没有提交:

session2也是同样操作id=1的数据行:被阻塞,只能等待下面是阻塞久了

session1提交更新:

解除阻塞,更新正常进行

提交commit

如果session1操作id=1的数据行,session2操作id=2的数据行会怎么样??

各自互不影响

各自互不影响

  3.3、Innodb存储引擎的表在没有使用索引时-行锁变表锁

无索引行锁升级为表锁

session1 session2

在hangsuo表中没有索引:

对id=1的数据行加行锁:

MySQL锁机制_第5张图片

表被锁了,对表的增删改对不可以

等待

提交commti:

对之前的更新回滚,不提交。

  3.4、间隙锁的危害

【什么是间隙锁】

当使用范围条件而不是等值检索,并请求共享或者排它锁时,Innodb会给符合条件的已有的数据记录的索引项加锁,对于键值在条件范围中的记录但是表中没有记录,叫间隙。

Innodb会对这个”间隙“加锁,这个机制就叫”间隙锁。

MySQL锁机制_第6张图片

危害:造成在锁定的时候无法插入锁定键值范围内的任何数据。在某些场景下可能对造成很大危害。

3.5、面试题:如何锁定一行

MySQL锁机制_第7张图片

锁定某一行,其对该行的其他事务对其操作会被阻塞,除非锁定行的会话结束commit

3.6、如何分析行锁定

通过检查 innodb_row_lock状态变量分析系统上的行锁的争夺情况。

mysql> show status like 'innodb_row_lock%';
+-------------------------------+--------+
| Variable_name                 | Value  |
+-------------------------------+--------+
| Innodb_row_lock_current_waits | 0      |
| Innodb_row_lock_time          | 418625 |
| Innodb_row_lock_time_avg      | 32201  |
| Innodb_row_lock_time_max      | 51886  |
| Innodb_row_lock_waits         | 13     |
+-------------------------------+--------+
5 rows in set (0.00 sec) 

五项中红色标明的是比较重要的:

Innodb_row_lock_current_wait :当前正在等待锁定的数量

Innodb_row_lock_time:从系统启动到现在锁定总时间长度

nnodb_row_lock_time_avg:每次等待所花的平均时间

Innodb_row_lock_time_max:从系统启动到现在等待最长的一次所花时间

Innodb_row_lock_waits  :系统启动后到现在总共等待的次数

5、悲观锁与乐观锁

(1)悲观锁:顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。

传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。

(2)乐观锁: 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。

乐观锁适用于多读的应用类型,这样可以提高吞吐量。

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