MySql中的行锁和表锁的理解

mysql 的 InnoDB引擎支持行锁,与Oracle不同,mysql的行锁是通过索引加载的,即是行锁是加在索引响应的行上的,要是对应的SQL语句没有走索引,则会全表扫描。

表锁:不会出现死锁,发生锁冲突几率高,并发低。
行锁:会出现死锁,发生锁冲突几率低,并发高。
锁冲突:例如说事务A将某几行上锁后,事务B又对其上锁,锁不能共存否则会出现锁冲突。(但是共享锁可以共存,共享锁和排它锁不能共存,排它锁和排它锁也不可以)。
死锁:例如说两个事务,事务A锁住了1-5行,同时事务B锁住了6-10行,此时事务A请求锁住6-10行,就会阻塞直到事务B施放6-10行的锁,而随后事务B又请求锁住1-5行,事务B也阻塞直到事务A释放1~5行的锁。死锁发生时,会产生Deadlock错误。

锁是对表操作的,所以自然锁住全表的表锁就不会出现死锁。

共享锁:读锁。当一个事务对某几行上读锁时,允许其他事务对这几行进行读操作,但不允许其进行写操作,也不允许其他事务给这几行上写锁。(读写锁不能共存,读的时候不能让其它事务进行写操作,更不能上写锁,如果其其它事务对同一行上读锁的话会造成该事务的阻塞)。
排它锁又称:写锁。当一个事务对某几行上写锁时,不允许其他事务写,但允许读(如果读也就是查,不上读锁可能是脏读,上读锁之后等待对应事务提交或者回滚后方可读到实时数据)。更不允许其他事务给这几行上任何锁(读锁会阻塞)。包括写锁。
上共享锁的写法:lock in share mode(读)例如: select  math from zje where math>60 lock in share mode;
上排它锁的写法:for update(写)              例如:select math from zje where math >60 for update;
注意几点:
1、行锁必须有索引才能实现,否则会自动锁全表,那么就不是行锁了。
2、两个事务不能锁同一个索引(不能有锁住有交集的行)  
例如:
事务A先执行:select math from zje where math>60 for update;
 事务B再执行:select math from zje where math<60 for update;
这样的话,事务B是会阻塞的。如果事务B把 math索引换成其他索引就不会阻塞,但注意,换成其他索引锁住的行不能和math索引锁住的行有重复
3、insert ,delete , update在事务中都会自动默认加上排它锁(写)。
会话1:select  math  from zje where math>60 for update;
会话2:update zje set math=99 where math=68;阻塞...........
如上,会话1先把zje表中math>60的行上排它锁。然后会话2试图把math=68的行进行修改,math=68处于math>60中,所以是已经被锁的,会话2进行操作时,就会阻塞,等待会话1把锁释放。当commit时或者程序结束时,会释放锁。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值