MySQL 的锁机制
一、读锁与写锁
- 读锁:共享锁、Shared Locks、S 锁
- 写锁:排他锁、Exclusive Locks、X 锁
- select:不加锁
name | X 锁 | S 锁 |
---|---|---|
X 锁 | 冲突 | 冲突 |
S 锁 | 冲突 | 不冲突 |
二、读操作
对于普通的 select 语句。innodb 不会加任何锁
select ... lock in share mode
将查找到的数据加上一个s锁,允许其他事务继续获取这些记录的 s 锁,不能获取这些记录的x锁(会阻塞)
使用场景:读取数据后,其他事务不能修改,但是自己也不一定能修改,因为其他事务也可以使用 select ... lock in share mode 继续加读锁。
select ... for update
将查找到的数据加上一个X锁,不允许其他事务获取这些记录的X锁和S锁
使用场景:读取数据后,其他事务既不能写,也不能加读锁,那么就导致只有自己可以修改数据。
三、写操作
- DELETED:删除一条数据时,先对记录加X锁,再执行删除操作。
- INSERT:插入一条记录时,会先加“隐式锁”来保护这条新插入的记录再本事务提交前不被别的事务访问到。
- UPDATE:如果被更新的列,修改前后没有导致存储空间变化,那么会先给记录加X锁,再直接对记录进行修改。
如果被更新的列,修改前后导致存储空间发生了变化,那么会先给记录加X锁,然后将记录删除掉,再insert一条新记录。
隐式锁:一个事务插入一条记录后,还未提交,这条记录会保存本次事务id,而其他事务如果想来对这个记录加锁时会发生事务 id 不对应,这时会产生 X 锁,所以相当于在插入一条记录时,隐式的给这条记录加了一把隐式 X 锁。
四、表锁 与 行锁
行锁
- LOCK_REC_NOT_GAP:单个行记录上的锁
- LOCK_GAP:间隙锁,锁定一个范围,但不包括记录本事,GAP 锁的目的,是为了防止同一事务的两次当前读,出现幻读的情况
- LOCK_ORDINARY:锁定一个范围,并且锁定记录本身。对于行的查询,都是采用该方法,主要目的是解决幻读的问题。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论