以下纯属个人总结,事务模式是repeatable read,有问题欢迎指正:
很重要的一点:尽管我们的SQL中使用了索引,但是如果该索引的区分数据度不高,在SQL执行时,原计划的锁可能升级为表锁(如一个索引有较多重复的数据)
- 查询(select)数据:select xxx from xxx where xxx for update
- where中没有使用索引,锁表
- where中使用索引且记录存在,锁记录(X锁)同时锁该记录所在数据页的数据,即锁区间(S锁)(一个页空间可能包含了多条数据,16K)
- where中使用索引且记录不存在,无锁
- 查询(select)数据:select xxx from xxx where xxx
- 快照读,无锁
- 查询(select)数据:select xxx from xxx where xxx lock in share mode
- 同select xxx from xxx where xxx for update,只是锁记录使用S锁
- 更改(update和delete)数据:
- 使用索引满足条件的记录存在,锁记录
- 使用索引满足条件的记录不存在,在该记录前后存在的记录间,加区间锁,锁区间(同时锁定左侧的边界记录,及左闭右开)(防止幻读的放生)
- 没有使用索引,锁表
- 添加(insert)数据:
- 存在表锁,阻塞
- 存在区间锁(范围锁),且索引列要插入的值在区间内,阻塞,否则不阻塞