MySQL中锁机制

在并发操作中,锁是必不可少的一部分,所以数据库中的锁也是必不可少的。

MySQL锁定机制类型

在不同的存储引擎采取的锁机制不同,mysql中存在三种机制,从小到大依次是:行锁,页锁,表锁;

1.行级锁定

锁的颗粒度很小,每次锁定只锁定一行数据,其他事务可以对其他行进行操作,所以发生所冲突的几率也很小,大大提交了并发性,但是频繁的加锁和解锁对系统性能也有很大消耗,同级锁定也更容易发生死锁。一般采用行级锁定的引擎有innodb引擎和NDB Cluster引擎。

 

2.页级锁定

每次事务进行操作的时候锁定当前页,并发能力以及消耗系统资源处于行锁和表锁之间,使用页级锁定的引擎有BerkeleyDB储存引擎。

 

3.表级锁定

事务操作的时候锁定当前表,锁的粒度非常大,对并发很不友好,但是消耗系统资源较少,通常采用表级锁定的引擎:MyISAM,Memory,CSV.

锁的种类

 MySQL中有不同的锁种类,他们对不同的操作有不同的锁定范围以及内容。MySQL默认自动提交,所以在平常使用的时候感觉不出来,如果需要测试锁机制需要把自动提交关闭即set autocommit =0;因为在不同的引擎中加锁的粒度不同,会加上不同的锁,比如innodb引擎中会加行锁,即锁定当前操作行,在myisam引擎中会加表锁,即锁定当前操作表。

但是根据执行的sql语句不同又细分为读锁(查询)以及写锁(增删改)。

MySIAM引擎中:

MySIAM中采用悲观锁机制,即会在读写操作的时候都会自动加锁,并且不支持事务。在读操作的时候会加读锁,写操作的时候加上写锁。

读锁(共享锁):加锁后其他事务能正常读取锁定表的数据,但是不能进行写操作,自身事务可以对锁定表进行读操作,但是不能进行写操作,不能对其他表进行任何操作。

写锁(排他锁):加锁后其他事务不能对锁定的表进行任何操作,自身事务可以对锁定的表进行读写操作,不能对其他表进行任何操作。

显式加锁:

#显示加读锁
lock table 表名  read;

#显示加写锁
lock table 表名 write;

#解锁
unlock tables;

InnoDB引擎中:

InnoDB采用乐观锁机制,在读操作的时候不会自动加锁,在写操作的时候会加上排他锁,支持事务,加锁的级别与事务隔离级别直接相关。

隔离级别相关,请移步我另一篇文章:https://blog.csdn.net/huaixiaohai_1/article/details/89923326

加锁方式:

#加共享锁
select * from 表名  where 限制条件 lock in share mode;

#加排他锁
select * from 表名 where 限制条件 for update

注意:在InnDB中排他锁和共享锁与MYISAM中有多不同,在innodb中,在一个事务对一行内容加上共享锁之后,其他事务可以访问锁定的内容,但是不可以对该行内容进行写操作,但是其他事务可以重复锁定(只能用共享锁)该行内容,这样也大大避免了锁冲突。

排他锁,在一个事务在一行内容加上排他锁之后,其他事务可以访问,同样不可以进行写操作,其他事务不能重复锁定该行内容。

innodb中的锁是针对索引加的锁,所以当没有使用索引或者索引失效的时候,会使用表锁。

间隙锁

      间隙锁是行锁的一种特殊情况,是在一个范围内没有的表中没有数值也会被锁定。

   

#查询id在1-10之间的数据
select * from table where id >1 and id <10;
#好比表中并没有id=4的数据,但是如果我们对id=4的数据进行删除操作,同样不会被删除,会被锁住。

意向锁:

    考虑下面一个情况:

    会话A对表进行数据操作,锁住了一行数据,会话B对表进行数据操作,由于没有采用索引或索引失效需要锁住整个表,这无疑是一种锁冲突的情况,那在会话B进行申请表锁的时候,数据库要怎么判断这个冲突呢?

  1.判断此表是否被其他事务锁住了整张表。

 2.判断每行数据是否被其他事务锁住了该行。

因为2中需要去遍历整张表,这无疑是一个非常耗资源的操作,为了更好的解决这个问题就引入了意向锁。

在意向锁存在的情况下,事务需要先去申请意向共享锁,成功后再申请该行的行锁。

上面步骤可改为:

1.不变 

2.查看是否存在意向共享锁,如果存在则说明表中有些数据被锁定了,则会阻塞加锁操作。

申请意向锁是数据库自动执行的,无需程序员用代码去实现。

查询加锁情况:

show open tables;

 

行锁分析:

show status like '%innodb_row_lock%';

参数1:当前正在等待的锁的数量;

参数2:等待总时长,从系统启动到现在;

参数3:平均等待时长;

参数4:最大的一次等待时间;

参数5:等待的次数;

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值