MySql锁
- 加锁的目的
- 事务和锁的区别
- 锁的分类
- 各个事务如何通过锁实现
- 死锁的条件及解决办法
- mysql锁的是实际应用
一、加锁的目的
锁机制用于管理对共享资源的并发访问,是对数据库的一种保护机制,也是数据库在事务操作中保证事务数据一致性和完整性的一种机制。当有多个用户并发的去存取数据时,在数据库中就可能会产生多个事务同时去操作一行数据的情况,如果我们不对此类并发操作不加以控制的话,就可能会读取和存储不正确的数据,最终破坏了数据的一致性;
综上:
- 锁是管理对公共资源的并发控制
- 加锁解决了多用户环境下保证数据库完整性和一致性
二、事务和锁的区别
事务与锁是不同的。事务具有ACID
( 原子性、一致性、隔离性和持久性),锁是用于解决隔离性的一种机制。事务的隔离级别通过锁的机制来实现。
使用锁的对象是事务,事务用来锁定数据库的对象是表 页 行 。并且一般锁定的对象仅在事务提交或者回滚后进行释放。(不同的事务隔离级别释放的时间也可能不同)
三、锁的分类
基于锁的属性分类:共享锁、排他锁。
基于锁的粒度分类:表锁、页锁、行锁(记录锁、间隙锁、临键锁)。
基于锁的状态分类:意向共享锁、意向排它锁。
锁的粒度:
MySQL 不同的存储引擎支持不同的锁机制,所有的存储引擎都以自己的方式显现了锁机制,服务器层完全不了解存储引擎中的锁实现:
- MyISAM 和 MEMORY 存储引擎采用的是表级锁(table-level locking)
- BDB 存储引擎采用的是页面锁(page-level locking),但也支持表级锁
- InnoDB 存储引擎既支持行级锁(row-level locking),也支持表级锁,但默认情况下是采用行级锁。
默认情况下,表锁和行锁都是自动获得的, 不需要额外的命令。
但是在有的情况下, 用户需要明确地进行锁表或者进行事务的控制, 以便确保整个事务的完整性,这样就需要使用事务控制和锁定语句来完成。
1、全局锁
MySQL 提供了一种加全局读锁的方法。全局锁就是对整个数据库进行加锁。当你需要让整个库处于只读状态的时候,可以使用这个命令,之后的其他线程的以下语句会被阻塞:数据DML的更新操作(数据的增删改)、数据DDL的定义语句(包括建表、修改表结构等)和事务更新类的提交语句。
命令:
Flush tables with read lock (FTWRL)
set global readonly=true
应用场景:
1、 使用mysqldump做全库逻辑备份;
2、 主库在做完全库逻辑备份后在从库上做主从配置。使用mysqldump做初始化工作。
关于mysqldump扩展链接:
https://blog.csdn.net/zhou920786312/article/details/123354503
在有些系统中,readonly 的值会被用来做其他逻辑,比如用来判断一个库是主库还是备库。因此,修改 global 变量的方式影响面更大,不建议使用。
2、表锁
锁整张表,并发度低
表级锁是mysql锁中粒度最大的一种锁,表示当前的操作对整张表加锁,资源开销比行锁少,不会出现死锁的情况,但是发生锁冲突的概率很大,因为同一张表上任何时刻只能有一个更新在执行。被大部分的mysql引擎支持,MyISAM和InnoDB都支持表级锁,但是InnoDB默认的是行级锁。
在上锁之后,一个用户在对表进行写操作(插入、删除、更新等)时,需要先获得写锁(也叫排斥锁),这会阻塞其它用户对该表的所有读写操作。没