两个事务先后select … where indexA =xxx limit 1 for update,试图给索引indexA在xxx处的首个位置加锁,之后update被锁定记录在索引字段indexA上的值
慢事务会阻塞,直到快事务update 索引字段的值并且commit从而改变索引的树形结构。这时慢事务select … where indexA =xxx limit 1 for update的目标记录发生了变化,因为for update 一直都是实时读。慢事务将选中最新一条indexA=xxx的记录,它和快事务选中的不是同一条
For example:
tb_people
| id | age |
|---|---|
| 1 | 10 |
| 2 | 10 |
id是主键,age上有index
| 事务1 | 事务2 | 说明 |
|---|---|---|
| START TRANSACTION; | - | 开启事务1 |
| - | START TRANSACTION; | 开启事务2 |
| select * from tb_people where age = 10 limit 1 for update | - | 事务1给index_age首个值为10的节点加锁,成功 |
| - | select * from tb_people where age = 10 limit 1 for update | 事务2也尝试给index_age首个值为10的节点加锁,被事务1阻塞 |
| update tb_people set age = 11 where id = 1 | - | 事务1更新选中记录,同时改变index_age的索引结构 |
| commit | - | 事务1提交。注意,commit完成的同时,事务2的select for update不再阻塞,但是被事务2选中的是id=2, age=10的记录 |
| - | commit |









网友评论