- RC隔离级别下,
- 对非索引字段更新,有个锁全表记录的过程,
- 不符合条件的会及时释放行锁,没必要等事务结束时释放;
- RC没有间隙锁的概念
- 而直接用索引列更新,只会锁索引查找值和行。
- update产生的X锁在不释放的状况下,
- DELETE语句没法执行,
- 但是UPDATE语句能更新不符合以前X锁的记录。
- update产生的X锁在不释放的状况下,
- 对非索引字段更新,有个锁全表记录的过程,
- RR隔离级别下,为保证binlog记录顺序,
- 非索引更新会锁住全表记录,
- 且事务结束前不会对不符合条件记录有逐步释放的过程。
- DELETE和UPDATE语句都不能执行
版本5.7.13
rc模式下:
session 1:
begin;
select * from t where c=5 for update;
session 2:
delete from t where c=10 --等待
session 3:
insert into t values(100001,8) --成功session
session 4 : update t set c=100 where id=10 -- 成功
session 1:
commit
session 2:事务执行成功
rr模式下:
begin;
select * from t where c=5 for update;
session 2:
delete from t where c=10 --等待
session 3:
insert into t values(100001,8) --等待spa
session 4 : update t set c=100 where id=10 --等待
session 1:
commit
session 2:事务执行成功
session 3:事务执行成功
从上面这两个简单的例子,能够大概看出上锁的流程.
无论是rr模式仍是rc模式,这条语句都会先在server层对表加上MDL S锁,而后进入到引擎层。
rc模式下,因为数据量不大只有10W。经过实验能够证实session 1上来就把该表的全部行都锁住了。
致使其余事务要对该表的全部现有记录作更新,是阻塞状态。为何insert又能成功?
说明rc模式下for update语句没有上gap锁,因此不阻塞insert对范围加插入意向锁,因此更新成功。
session 1commit后,session 2执行成功。代表全部行的x锁是在事务提交完成之后才释放。
rr模式下,session 1和session 2与rc模式下都同样,说明rr模式下也对全部行上了X锁。
惟一的区别是insert也等待了,是由于rr模式下对没有索引的更新,聚簇索引上的全部记录,都被加上了X锁。其次,聚簇索引每条记录间的间隙(GAP),也同时被加上了GAP锁。因为gap锁阻塞了insert要加的插入意向锁,致使insert也处于等待状态。只有当session 1 commit完成之后。session 1上的全部锁才会释放,S2,S3执行成功
因为例子中的数据量还比较小,若是数据量达到千万级别,就比较直观的能看出,上锁是逐行上锁的一个过程.扫描一条上一条,直到全部行扫描完,rc模式下对全部行上x锁。rr模式下不只对全部行上X锁,还对全部区间上gap锁.直到事务提交或者回滚完成后,上的锁才会被释放。server