MySQL从入门到精通(九) MySQL锁,各种锁 锁是计算机协调多个进程或线程并发访问某一资源的机制,在数据库中,除传统的计算资源(CPU、RAM、I/O)争用外 , 数据也是一种供许多用户共享的资源,如何保证数据并发访问的一致性,有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素,从这个角度来说,锁对数据库而言是尤其重要,也更加复杂 。MySQL中的锁,按照锁的粒度分为:1、全局锁,就锁定数据库中的所有表 。2、表级锁,每次操作锁住整张表 。3、行级锁,每次操作锁住对应的行数据 。
全局锁就是对整个数据库实例加锁,加锁后整个实例就处于只读状态,后续的DML的写语句,DDL语句,已经更新操作的事务提交语句都将阻塞 。其典型的使用场景就是做全库的逻辑备份,对所有的表进行锁定 , 从而获取一致性视图,保证数据的完整性 。但是对数据库加全局锁是有弊端的,如在主库上备份,那么在备份期间都不能执行更新,业务会受影响,第二如果是在从库上备份,那么在备份期间从库不能执行主库同步过来的二进制日志,会导致主从延迟 。
解决办法是在innodb引擎中,备份时加上--single-transaction参数来完成不加锁的一致性数据备份 。
添加全局锁: flush tables with read lock; 解锁 unlock tables 。
表级锁,每次操作会锁住整张表.锁定粒度大,发送锁冲突的概率最高,并发读最低,应用在myisam、innodb、BOB等存储引擎中 。表级锁分为: 表锁、元数据锁(meta data lock, MDL)和意向锁 。
表锁又分为: 表共享读锁 read lock、表独占写锁write lock
语法: 1、加锁 lock tables 表名 ... read/write
2、释放锁 unlock tables 或者关闭客户端连接
注意: 读锁不会阻塞其它客户端的读,但是会阻塞其它客户端的写,写锁既会阻塞其它客户端的读,又会阻塞其它客户端的写 。大家可以拿一张表来测试看看 。
元数据锁,在加锁过程中是系统自动控制的 , 无需显示使用,在访问一张表的时候会自动加上,MDL锁主要作用是维护表元数据的数据一致性,在表上有活动事务的时候,不可以对元数据进行写入操作 。为了避免DML和DDL冲突,保证读写的正确性 。
在MySQL5.5中引入了MDL,当对一张表进行增删改查的时候 , 加MDL读锁(共享);当对表结构进行变更操作时,加MDL写锁(排他).
查看元数据锁:
select object_type,object_schema,object_name,lock_type,lock_duration from performance_schema_metadata_locks;
意向锁,为了避免DML在执行时,加的行锁与表锁的冲突,在innodb中引入了意向锁 , 使得表锁不用检查每行数据是否加锁,使用意向锁来减少表锁的检查 。意向锁分为,意向共享锁is由语句select ... lock in share mode添加 。意向排他锁ix,由insert,update,delete,select 。。。for update 添加 。
select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_lock;
行级锁 , 每次操作锁住对应的行数据,锁定粒度最?。?发生锁冲突的概率最高 , 并发读最高 , 应用在innodb存储引擎中 。
innodb的数据是基于索引组织的,行锁是通过对索引上的索引项加锁来实现的,而不是对记录加的锁,对于行级锁,主要分为以下三类:
1、行锁或者叫record lock记录锁,锁定单个行记录的锁,防止其他事物对次行进行update和delete操作,在RC,RR隔离级别下都支持 。
2、间隙锁Gap lock,锁定索引记录间隙(不含该记录) , 确保索引记录间隙不变,防止其他事物在这个间隙进行insert操作,产生幻读,在RR隔离级别下都支持 。
3、临键锁Next-key-lock,行锁和间隙锁组合,同时锁住数据 , 并锁住数据前面的间隙Gap,在RR隔离级别下支持 。
innodb实现了以下两种类型的行锁
1、共享锁 S: 允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁 。
2、排他锁 X: 允许获取排他锁的事务更新数据,阻止其他事务获得相同数据集的共享锁和排他锁 。
insert 语句 排他锁 自动添加的
update语句 排他锁 自动添加
delete 语句 排他锁 自动添加
select 正常查询语句 不加锁。。。
select。。。lock in share mode 共享锁 需要手动在select 之后加lock in share mode
select。。。for update 排他锁 需要手动在select之后添加for update
默认情况下,innodb在repeatable read事务隔离级别运行,innodb使用next-key锁进行搜索和索引扫描 , 以防止幻读 。
间隙锁唯一目的是防止其它事务插入间隙,间隙锁可以共存,一个事务采用的间隙锁不会阻止另一个事务在同一间隙上采用的间隙锁 。
mysql中的乐观锁和悲观锁怎么用关于mysql中的乐观锁和悲观锁面试的时候被问到的概率还是比较大的 。
mysql的悲观锁:
其实理解起来非常简单 , 当数据被外界修改持保守态度,包括自身系统当前的其他事务,以及来自外部系统的事务处理 , 因此,在整个数据处理过程中,将数据处于锁定状态 。悲观锁的实现 , 往往依靠数据库提供的锁机制,但是也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在自身系统中实现了加锁机制,也无法保证外部系统不会修改数据 。
来点实际的,当我们使用悲观锁的时候我们首先必须关闭mysql数据库的自动提交属性,因为MySQL默认使用autocommit模式,也就是说,当你执行一个更新操作后,MySQL会立刻将结果进行提交 。
关闭命令为:set autocommit=0;
悲观锁可以使用select…for update实现 , 在执行的时候会锁定数据,虽然会锁定数据,但是不影响其他事务的普通查询使用 。此处说普通查询就是平时我们用的:select * from table 语句 。在我们使用悲观锁的时候事务中的语句例如:
//开始事务
begin;/begin work;/start transaction; (三选一)
//查询信息
select * from order where id=1 for update;
//修改信息
update order set name='names';
//提交事务
commit;/commit work;(二选一)
此处的查询语句for update关键字,在事务中只有SELECT ... FOR UPDATE 或LOCK IN SHARE MODE 同一条数据时会等待其它事务结束后才执行 , 一般的SELECT查询则不受影响 。
执行事务时关键字select…for update会锁定数据,防止其他事务更改数据 。但是锁定数据也是有规则的 。
查询条件与锁定范围:
1、具体的主键值为查询条件
比如查询条件为主键ID=1等等,如果此条数据存在 , 则锁定当前行数据,如果不存在,则不锁定 。
2、不具体的主键值为查询条件
比如查询条件为主键ID1等等,此时会锁定整张数据表 。
3、查询条件中无主键
会锁定整张数据表 。
4、如果查询条件中使用了索引为查询条件
明确指定索引并且查到,则锁定整条数据 。如果找不到指定索引数据,则不加锁 。
悲观锁的确保了数据的安全性,在数据被操作的时候锁定数据不被访问,但是这样会带来很大的性能问题 。因此悲观锁在实际开发中使用是相对比较少的 。
mysql的乐观锁:
相对悲观锁而言,乐观锁假设数据一般情况下不会造成冲突,所以在数据进行提交更新的时候 , 才会对数据的冲突与否进行检测,如果发现冲突,则让返回用户错误的信息,让用户决定如何去做 。
一般来说,实现乐观锁的方法是在数据表中增加一个version字段 , 每当数据更新的时候这个字段执行加1操作 。这样当数据更改的时候,另外一个事务访问此条数据进行更改的话就会操作失败,从而避免了并发操作错误 。当然,还可以将version字段改为时间戳,不过原理都是一样的 。
例如有表student , 字段:
id,name,version
1a1
当事务一进行更新操作:update student set name='ygz' where id = #{id} and version = #{version};
此时操作完后数据会变为id = 1,name = ygz,version = 2,当另外一个事务二同样执行更新操作的时候,却发现version != 1,此时事务二就会操作失败,从而保证了数据的正确性 。
悲观锁和乐观锁都是要根据具体业务来选择使用,本文仅作简单介绍 。
mysql中锁的类型有哪些全局锁
顾名思义,全局锁就是对整个数据库实例加锁 。MySQL 提供mysql全局锁怎么用了一个加全局读锁的方法,命令是 Flush tables with read lock (FTWRL) 。当你需要让整个库处于只读状态的时候,可以使用这个命令,之后其他线程的以下语句会被阻塞:数据更新语句(数据的增删改)、数据定义语句(包括建表、修改表结构等)和更新类事务的提交语句 。
表级锁
MySQL 里面表级别的锁有两种:一种是表锁,一种是元数据锁(meta data lock , MDL) 。
表锁
表锁的语法是 lock tables … read/write 。与 FTWRL 类似,可以用 unlock tables 主动释放锁,也可以在客户端断开的时候自动释放 。需要注意,lock tables 语法除mysql全局锁怎么用了会限制别的线程的读写外 , 也限定mysql全局锁怎么用了本线程接下来的操作对象 。
元数据锁
MDL 不需要显式使用,在访问一个表的时候会被自动加上 。MDL 的作用是,保证读写的正确性 。你可以想象一下,如果一个查询正在遍历一个表中的数据,而执行期间另一个线程对这个表结构做变更,删了一列,那么查询线程拿到的结果跟表结构对不上,肯定是不行的 。
【mysql全局锁怎么用 0p手机忘记密码怎样打开】关于mysql全局锁怎么用和0p手机忘记密码怎样打开的介绍到此就结束了 , 不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站 。
推荐阅读
- 怎么把文本复制到电视盒子,电视怎么复制文字
- 打java代码,打java代码的软件
- 手机无预览器怎么下载软件,手机无预览器怎么下载软件安装
- 怎么申请做手机直播主播,怎么开通手机直播平台
- 求最大值函数python 求最大值函数是什么?求最小值函数是什么?
- 为什么视频会有雪花点,视频有雪花什么原因
- b站电影直播游戏过程视频,b站电影直播游戏过程视频怎么看
- fir窗函数滤波c语言 窗函数设计fir滤波器的优缺点
- .net和asp.net,net和aspnet的区别