MySQL的锁机制使用详解

 更新时间:2024年04月02日 10:45:31   作者:今吴霜.  
这篇文章主要介绍了MySQL的锁机制使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

一、锁分类

MySQL的锁主要分为3大类

(1)、表级锁:存储引擎为Myisam。锁住整个表,特点是开销小,加锁快,锁定力度大,发生锁冲突的概率最高,并发度最低。

(2)、页级锁:存储引擎为BDB。锁住某一页的数据(16kb左右),特点:开销和枷锁时间介于表级和行级之间;会出现死锁,锁定力度介于表锁和行锁之间,并发度一般。

(3)、行级锁:存储引擎为innodb。锁住某一行的数据,特点:锁的实现更加复杂,开销大,加锁速度慢。

根据以上特点,仅从锁的角度来说:

表级锁更适合于以查询为主,只有少量按索引条件更新数据的应用,如Web应用;

而行级锁则更适合于有大量按索引条件并发更新少量不同数据,同时又有并发查询的应用,如一些在线事务处理(OLTP)系统。

二、行级锁分类

行级锁主要分为以下7类

(1)、共享/排他锁(shared/exclusive lock)

(2)、意向锁(intention lock)

(3)、记录锁(record lock)

(4)、间隙锁(gap lock)

(5)、临建锁(next-key lock)

(6)、插入意向锁(insert intention lock)

(7)、自增锁(auto-inc lock)

2.1 共享/排他锁

2.1.1 共享锁

共享锁:又称S锁、读锁,可以允许读,但不能写。

共享锁可以与共享锁一起使用。

select ... from table_name lock in share mode;

2.1.2 排他锁

排他锁:又称X锁、写锁,不能允许读,也不能允许写,排他锁不能与其他所一起使用。

select ... from table_name for update;

mysql中,update,delete,insert,alter 这些写的操作默认都会加上排他锁。

select 默认不会加任何锁类型。

一旦写数据的任务没有完成,数据是不能被其他任务读取的,这对并发操作有较大的影响。

共享/排他锁的释放方式: commit、rollback

2.2 意向锁

innoDB 为了支持多粒度的锁,即允许行级锁和表级锁共存,而引入意向锁。

意向锁是指未来的某个时刻,事务可能要加共享/排他锁,先提前声明一个意向。

这样如果有人尝试对全表进行修改,就不需要判断表中的数据是否被加锁了,只需要通过等待意向互斥锁被释放就行了。

2.2.1 意向共享锁(IS):事务想要在获得表中某些记录的共享锁,需要在表上先加意向共享锁。

2.2.2 意向互斥锁(IX):事务想要在获得表中某些记录的互斥锁,需要在表上先加意向互斥锁。

意向锁其实不会阻塞全表扫描之外的任何请求,它们的主要目的是为了表示是否有人请求锁定表中的某一行数据。

2.3 记录锁

单个行记录上的锁。记录锁总是会锁住索引记录,如果innoDB存储引擎表

在建立的时候没有设置任何一个索引,那么innoDB存储引擎会使用隐式的主键来进行锁定。

2.4 间隙锁

间隙锁锁住记录中的间隔,即范围查询的记录。

select * from table_name where id between 1 and 10 for update;

这个脚本会锁住1到10的数据,以防止其他事务修改该区间的记录;

间隙锁的主要目的,就是为了防止其他事务在间隔中插入数据,以导致“不可重复读”。

如果把事务的隔离级别降级为读提交(Read Committed, RC),间隙锁则会自动失效

查看innodb_locks_unsafe_for_binlog是否禁用:

show variables like 'innodb_locks_unsafe_for_binlog';

2.5 临建锁

临建锁是记录锁和间隙锁的组合,锁的范围既包含记录又包含索引区间。

默认情况下,innoDB使用临建锁来锁定记录。

但当查询的索引含有唯一属性的时候,临建锁会进行优化,将其降级为记录锁,即仅锁住索引本身,不是范围。

临键锁的主要目的,也是为了避免幻读(Phantom Read)。

如果把事务的隔离级别降级为RC,临键锁则也会失效。

2.6 插入意向锁

对已有数据行的修改和删除,必须加互斥锁,对于数据的插入,加插入意向锁。

是专门针对于insert操作的。

2.7 自增锁

是一种特殊的表级别的锁,专门针对事务插入auto-increment类型的列。

最简单的情况,如果一个事务正在往表中插入记录,所有其他事务的插入必须等待,以便第一个事务插入的行,是连续的主键值。

三、其他锁

接下看讲一下其他的锁:

3.1 死锁

产生是因为线程锁之间交替等待产生的。

值两个或两个以上的事务在执行过程中,因争夺资源而造成的一种相互等待的现象。

MySQL处理死锁的方法:根据数据写的数据量的大小来回滚小事务。

3.2 乐观/悲观锁

乐观锁:乐观的假定大概率不会发生并发更新冲突,访问,处理数据的过程中不加锁,只在更新数据时根据版本号或时间戳判断是否有冲突,有则处理,无责提交事务。

如果系统并发量非常大,悲观锁会带来非常大的性能问题,选择使用乐观锁,现在大部分应用属于乐观锁

悲观锁:悲观的假定大概率会发生并发更新冲突,访问,处理数据前就加排他锁,在整个数据处理过程中锁定数据,事务提交或回滚后才释放锁。

优点

  • 悲观并发控制实际上是“先取锁再访问”的保守策略,为数据处理的安全提供了保证。

缺点

(a)在效率方面,处理加锁的机制会让数据库产生额外的开销,还有增加产生死锁的机会;

(b)在只读型事务处理中由于不会产生冲突,也没必要使用锁,这样做只能增加系统负载;还有会降低了并行性,一个事务如果锁定了某行数据,其他事务就必须等待该事务处理完才可以处理那行数

3.3 表级锁

表级读锁:

lock table table_name read;

表级写锁:

lock table table_name write;

释放锁

unlock tables;

四、建议

(1)、控制事务的大小(操作写的数据量)

(2)、使用锁的时候尽量要配合与携带索引的字段使用,避免升级为表锁

(3)、范围查询,尽量减少基于范围查询的事务的大小

(4)、如果业务必须要使用锁,锁的冲突特别高的话,改为表锁

(5)、可以根据项目自身的情况调节事务的innodb_flush_log_at_trx_commit

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持程序员之家。

相关文章

  • MySQL数据库中遇到no?database?selected问题解决办法

    MySQL数据库中遇到no?database?selected问题解决办法

    这篇文章主要给大家介绍了关于MySQL数据库中遇到no?database?selected问题的解决办法,这是MySQL数据库的错误提示,意思是没有选择数据库,在使用MySQL命令行操作时需要先选择要操作的数据库,否则就会出现这个错误,需要的朋友可以参考下
    2024-03-03
  • MYSQL与sqlyog连接的实现

    MYSQL与sqlyog连接的实现

    本文主要介绍了MYSQL与sqlyog连接的实现,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-10-10
  • MySQL中with?rollup的用法及说明

    MySQL中with?rollup的用法及说明

    这篇文章主要介绍了MySQL中with?rollup的用法及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • mysql安装忘记初始密码简单有效的解决方法

    mysql安装忘记初始密码简单有效的解决方法

    在本篇文章里小编给大家整理的是一篇关于mysql安装忘记初始密码简单有效的解决方法,有需要的朋友们参考学习下。
    2020-01-01
  • mysql-connector-java与Mysql、Java的对应版本问题

    mysql-connector-java与Mysql、Java的对应版本问题

    这篇文章主要介绍了mysql-connector-java与Mysql、Java的对应版本问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • mysql-8.0.35-winx64?zip版安装教程(附图文)

    mysql-8.0.35-winx64?zip版安装教程(附图文)

    许多人在学习过程中经常因使用不当将MySQL数据库搞崩溃,这篇文章主要给大家介绍了关于mysql-8.0.35-winx64?zip版安装教程的相关资料,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2024-01-01
  • 详解MySQL中的存取权限

    详解MySQL中的存取权限

    这篇文章主要介绍了详解MySQL中的存取权限,针对用户使用数据库权限分配的问题做出说明,需要的朋友可以参考下
    2015-07-07
  • SQL结果如何根据某个字段取最新时间去重

    SQL结果如何根据某个字段取最新时间去重

    在日常的项目开发当中,经常会遇到获取同一属性相同的记录,如何获取记录时间最新的那一条,下面这篇文章主要给大家介绍了关于SQL结果如何根据某个字段取最新时间去重的相关资料,需要的朋友可以参考下
    2023-06-06
  • SQL语句实现多表查询

    SQL语句实现多表查询

    这篇文章主要介绍了SQL语句实现多表查询,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参一下下面文章详细内容
    2022-07-07
  • MySql 5.7.21免安装版本win10下的配置方法

    MySql 5.7.21免安装版本win10下的配置方法

    这篇文章主要介绍了MySql 5.7.21免安装版本win10下的配置方法,本文图文并茂给大家介绍的非常详细,需要的朋友可以参考下
    2018-05-05

最新评论

?


http://www.vxiaotou.com