Mysql学习-锁

Mysql锁是什么?锁有哪些类别?

锁定义

同⼀时间同⼀资源只能被⼀个线程访问 update test set a=a-1 where id=100 and a> 0;
在数据库中,除传统的计算资源(如 CPU RAM I/O 等)的争⽤以外,数据也是⼀种供许多⽤户
共享的资源。如何保证数据并发访问的⼀致性、有效性是所有数据库必须解决的⼀个问题,锁冲突
也是影响数据库并发访问性能的⼀个重要因素。

锁的分类

从对数据操作的类型分法(读或写)
读锁(共享锁): 针对同⼀份数据,多个读操作可以同时进⾏⽽不会互相影响。
写锁(排它锁): 当前写操作没有完成前,它会阻断其他写锁和读锁。
从对数据操作的粒度分法
表级锁: 表级锁是 MySQL 中锁定粒度最⼤的⼀种锁,表示对当前操作的整张表加锁
⾏级锁: ⾏级锁是 Mysql 中锁定粒度最细的⼀种锁,表示只针对当前操作的⾏进⾏加锁
⻚级锁: ⻚级锁是 MySQL 中锁定粒度介于⾏级锁和表级锁中间的⼀种锁,⼀次锁定相邻的⼀组记
        录
从并发⻆度的分发 -- 实际上乐观锁和悲观锁只是⼀种思想
悲观锁 :对数据被外界(包括本系统当前的其他事务,以及来⾃外部系统的事务处理)修改持保守
        态度(悲观 ) ,因此,在整个数据处理过程中,将数据处于锁定状态。
乐观锁 :乐观锁假设认为数据⼀般情况下不会造成冲突,所以在数据进⾏提交更新的时候,才会正
        式对数据的冲突 与否进⾏检测,如果发现冲突了,则让返回错误信息再进⾏业务重试
其他锁:
间隙锁 :在条件查询中,如: where id>100 InnoDB 会给符合条件的已有数据记录的索引项加
        锁;对于键值在条 件范围内但并不存在的记录,叫做“ 间隙( GAP)” ,间隙的⽬的是为了防⽌
        幻读
意向锁:意向锁分为 intention shared lock (IS) 和 intention exclusive lock (IX),意向锁的⽬的就是
        表明有事务正在或者将要锁住某个表中的⾏

⾏锁与表锁的⽐较 

表级锁 MySQL 锁定粒度最⼤ 的⼀种锁,表示对当前操作的整 张表加锁,它实现简单。最常使
        ⽤的MYISAM与 INNODB 都⽀持表级锁定。
特点: 开销⼩,加锁快;不会出现死锁;锁定粒度⼤,发出锁 冲突的概率最⾼,并发度最低。
⾏级锁 Mysql 锁定粒度最细 的⼀种锁,表示只针对当前操作的⾏进⾏加锁。⾏级锁能⼤⼤减少
        数据库操作的冲突。其加锁粒度最⼩,但加锁的开销也最⼤。
特点: 开销⼤,加锁慢;会出现死锁;锁定粒度最⼩,发⽣锁冲突的概率最低,并发度也最⾼
使⽤: InnoDB⾏锁是通过给索引上的索引项加锁来实现的
只有通过索引条件检索数据,InnoDB才使⽤⾏级锁,否则,InnoDB将使⽤表锁

InnoDB死锁概念

定义:当两个或以上的事务相互持有和请求锁,并形成⼀个循环的依赖关系,就会产⽣死锁。多个
        事务同时锁定同⼀个资源时,也会产⽣死锁。在⼀个事务系统中,死锁是确切存在并且是不
  
        能完全避免的。
解决: InnoDB 会⾃动检测事务死锁,⽴即回滚其中某个事务,并且返回⼀个错误。它根据某种机
        制来选择那个最简单(代价最⼩)的事务来进⾏回滚

程序开发过程中应该如何注意避免死锁

锁的本质是资源相互竞争,相互等待,往往是两个(或以上)的 Session加锁的顺序不⼀致

如何有效避免:
在程序中,操作多张表时,尽量以相同的顺序来访问(避免形 成等待环路)
批量操作单张表数据的时候,先对数据进⾏排序(避免形成等 待环路) A 线程 id 1 ,10 ,20 按顺
序加锁 B 线程 id:20,10,1 如果可以,⼤事务化成⼩事务,甚⾄不开启事务 select for
update==>insert==>update = insert into update on duplicate key
尽量使⽤索引访问数据,避免没有 where 条件的操作,避免锁表 有⾛索引记录锁,没⾛索引表锁
使⽤等值查询⽽不是范围查询查询数据,命中记录,避免间隙锁对并发的影响 1 10 20 等值
where id in (1,10,20) 范围查询 id>1 and id<20
避免在同⼀时间点运⾏多个对同⼀表进⾏读写的脚本,特别注意加锁且操作数据量⽐较⼤的语句;
我们经常会有⼀些定时脚本,避免它们在同⼀时间点运⾏

Mysql间隙锁

间隙锁的定义:间隙锁是⼀个在索引记录之间的间隙上的锁

间隙锁的作⽤: RR 隔离级别保证对读取到的记录加锁 ( 记录锁 ) 同时保证对读取的范围加锁,新
        的满⾜查询条件的记录不能够插 ( 间隙锁 ) ,不存在幻读现象

select id,a,b from test where a=10 for update; 1 条满⾜的记录
update delete...
INSERT INTO test ( id , a , b ) VALUES (18, 10, 10);
select id,a,b from test where a=10; 2 条满⾜的记录
验证间隙锁的⽅式,建表 == 》开启两个 session== 》第⼀个 session进⾏锁操作== 》另⼀个 session
插⼊数据

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值