MySQL中的共享锁(lock in share mode)和排它锁(for update)

本文详细介绍了MySQL中的共享锁(lock in share mode)和排它锁(for update)。共享锁允许读取但阻止修改,而排它锁不仅阻止修改,还阻止其他事务加锁。在实际操作中,会话1对数据加锁后,会话2可以快照读但无法加锁或修改。总结中指出,共享锁适用于涉及多表一致性的情况,排它锁适用于单表操作的一致性需求。

数据库中新建一张表user:

CREATE TABLE `test_user` (
  `id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `name` VARCHAR(2) NOT NULL COMMENT '姓名',
  `age` INT(11) NOT NULL COMMENT '年龄',
  PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

往user表中插入两行数据:

INSERT INTO `test_user` (`id`,`name`,`age`) VALUES (1,'张三',23);
INSERT INTO `test_user` (`id`,`name`,`age`) VALUES (2,'李四',24);

特别说明:共享锁和排他锁均阻塞不了快照读 

1.共享锁(select ... lock in share mode)

一个事务对表中符合条件的数据行加了共享锁,这样的话其他事务可以读取(快照读)这些数据,也可以继续添加共享锁,但是无法修改这些数据直到你这个加锁的事务执行完成(否则会出现锁等待超时)。

会话1使用begin开启一个事务,对test_user表中的数据加了共享锁:

此时会话2使用begin也开启一个事务,对test_user表中的数据进行快照读,可以看到快照读时是可以读取到test_user表中的数据:

接着会话2再对test_user表中的数据加共享锁,如下图所示,可以看到还是读取到表中的数据: 

接着会话1继续对test_user表进行更新操作,可以看到会话1此时会阻塞:

这时会话2也对test_user表进行更新操作(注意执行更新操作的时间不要超过会话1的锁等待超时检测时间,即不要超过innodb_lock_wait_timeout设置的值),由于检测到了死锁,事务2会发生回滚:

这时原本阻塞的会话1会立马执行完成

2.排它锁(for update)

一个事务对表中符合条件的数据行加了排它锁,其他事务可以进行快照读,但是无法在这些记录上添加任何的排它锁或共享锁。即for update并不会阻塞其他事务的快照读取操作,除了select ...lock in share mode和select ... for update这种显示加锁的查询操作。

会话1使用BEGIN开启一个事务,对test_user表中的数据加了排它锁:

会话2使用BEGIN开启一个事务,对test_user表中的数据进行快照读,可以读取到数据:

会话2再对test_user表中的数据加共享锁,50秒后会出现锁等待超时:

会话2再对test_user表中的数据加排它锁,50秒后也会出现现锁等待超时:

接着会话2再次对test_user表中的数据加排它锁,出现锁等待:

然后此时会话1对开启的事务进行提交操作,可以看到上面会话2中阻塞的排它锁查询已经将查询结果查询出来了

 

3.使用总结

lock in share mode适用于两张表存在业务关系时的一致性要求,for  update适用于操作同一张表时的一致性要求。 

例如主表(t_parent)与子表(into t_child)间具有关联关系,可能在往子表插入数据的过程中对应的主表数据被删除掉,那么这个时候该怎么办了?

解决方法:

1.业务方法上添加事务注解@Transactional

2.对主表的记录加共享锁,即select * from t_parent lock where id=1 in share mode;

3.然后再往子表中插入记录:insert into t_child (...,parent_id) values (...,1);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值